作为一点背景知识,我正在用C语言为一台运行DOS专有版本的小型16位手持计算机编写一个抄表应用程序。
我有一个屏幕,它显示仪表信息并提示用户键入读数。当用户按下设备上的enter键时,将执行以下代码:
/* ...
* beginning of switch block to check for keystrokes
* ...
*/
case KEY_ENTER: {
/* show what has been entered */
if(needNew == 0) {
/* calculate usage for new reading */
double usg = 0;
int ret = CalculateNewUsage(vlr, buf, &usg);
VerifyReadScreen(vlr, ret, buf, &usg);
needRedraw = TRUE;
}
break;
}
/* .... end switch statement */vlr是一个指向保存所有帐户/计价器信息的结构的指针,buf的类型为char[21],用于存储在此块之上处理的读数的数字击键。当我在调用CalculateNewUsage之前和之后检查它们时,我的变量都包含有效数据。
然而,当我在输入VerifyReadScreen后再次检查变量数据时,newread指向内存中的某个随机位置,并返回看起来像版权声明的内容。有趣的是,无论我输入什么帐户或读数,屏幕上都会打印出VerifyReadScreen中newread的无效数据。我以与CalculateNewUsage相同的方式将地址传递给VerifyReadScreen,但不知何故我得到了不同的结果。
这是VerifyReadScreen
BYTE VerifyReadScreen(const VLRREC * vlr,
const int status,
const char * newread,
const double * usage) {
/* snip a whole bunch of irrelevant formatting code */
printf("%s", (*newread)); /* prints funky copyright text */
/* snip more irrelevant formatting code */
return TRUE;
} 感谢Jefromi指出,我在VerifyReadScreen中实际打印newread的代码应该是:
printf("%s", newread); /* yay! */因为我不需要取消引用newread,因为printf为我做了这件事。我本质上是在传递一个指向一个指针的指针,这个指针是内存中的某个任意位置。
发布于 2010-03-06 02:16:17
我想我有足够的信心把这篇文章作为答案:
BYTE VerifyReadScreen(const VLRREC * vlr, const int status, const char * newread, const double * usage) {
...
LCD_set_cursor_pos(19 - strlen(newread), 3);
printf("%s", (*newread)); /* prints funky copyright text */
...
}您已经获得了一个字符串(char*) newread,但是在这个printf中,您取消了对它的引用,这就得到了字符串的第一个字符。然后将其用作printf的%s的参数,因此它尝试转到该字符给出的内存地址,并打印它在那里找到的内容。
附注:你很不走运--一般来说,这样做可能会给你一个段错误,所以你可以追踪到那一行,并意识到那里有一个指针错误。
发布于 2010-03-06 02:20:27
我不知道这是否是您面临的问题,但是VerifyReadScreen中使用的21个字符的buffer很可能会溢出:
if(strlen((*vlr).ServAdd) >= 20) {
sprintf(buffer, "%20s", (*vlr).ServAdd);
}%20s格式说明符不会阻止sprintf写入超过20个字符。如果字符串少于20个字符(或者在if条件中需要<= 20?),它只用空格填充字符串。
else {
memset(buffer, 0x20, (int)(strlen((*vlr).ServAdd) / 2) + 1);
strcat(buffer, (*vlr).ServAdd);
}在这里,根据字符串的长度进行了一些填充,但是我不知道如何确保结果不超过20个字符。
https://stackoverflow.com/questions/2388822
复制相似问题