【问题标题】:static variable getting cleared when calling sprintf调用 sprintf 时清除静态变量
【发布时间】:2014-05-27 02:28:30
【问题描述】:

我遇到了一个显示一些奇怪行为的静态变量的问题。希望有人能帮忙,代码如下:

void digitRefresh(void){

static char digitenabled=1;

sprintf(digits, "%d", number+10000);

switch (digitenabled) {
    case 1: digitDecode(digits[1] - 48);
        CATHODE_1 = ENABLE;
        break;
    case 2: digitDecode(digits[2] - 48);
        CATHODE_2 = ENABLE;
        break;
    case 3: digitDecode(digits[3] - 48);
        CATHODE_3 = ENABLE;
        break;
    case 4: digitDecode(digits[4] - 48);
        CATHODE_4 = ENABLE;
        break;
}
delay_ms(DIGIT_DELAY);

disableAllCathodes();
return; 

}

顺便说一下,数字被定义为char digits[5];

正如你所看到的,我定义了一个局部静态变量,所以当这个函数被多次调用时,我可以跳转到程序的不同位置。

我刮胡子的问题在于第二行代码。当 sprintf 被执行时,var digitenabled 以某种方式将其值更改为零。正如您在代码中看到的那样,它之前是一个,但是在冲刺之后我放置了一个断点,由于某种原因它是一个零。

如果我不通过注释掉它来使用 sprintf,那么问题就会消失,并且变量的行为符合预期(不会被清除并在再次调用函数时保留该值。

sprintf 做错了吗?所以变量消失了?有什么想法吗?

这是在使用 XC8 编译器的微控制器 PIC16F1847 上。谢谢

【问题讨论】:

  • 数字是如何定义的?它需要是 char 数字[10],而不是 *digits。
  • 数字是否有足够的内存空间来保存所有数字?
  • 字符数字[5];作为全球。是的,程序中没有更多内容,我检查了数字数组,它包含了它应该包含的内容。

标签: c static printf pic reentrancy


【解决方案1】:

问题出在这里:

 char digits[5];   // from comment -jelipito

 sprintf(digits, "%d", number+10000);  // from question code.

假设number = 0。

sprintf() 正在将“10000”加上一个字符串终止字符写入digits,总共 6 个字符。然而,digits 是一个只有五个字符的数组。写入数组末尾会导致不可预测的结果。

char digits[5]; 重新定义为char digits[50];,或者一个大到足以容纳sprintf() 函数的输出的东西。

您可能会考虑的另一个 safety-net 是将 sprint() 替换为 snprintf()

 snprintf(digits, sizeof(digits), "%d", number+10000);

snprintf() 函数的写入不会超出数字数组的大小(就像 sprintf() 一样)。相反,它将截断输出(如有必要)以防止这样做。

【讨论】:

  • 非常感谢!是的,这就是问题所在。我忘记了 sprintf 中的空字符。
【解决方案2】:

这里的问题是char digits[5]。对sprintf 的调用导致digits 变量超出其界限,这意味着未定义的行为反过来会导致有趣的事情发生!

请选择使用更安全的调用 snprintf,但请注意,snprintf 会遇到一些通过手册页明确说明的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-08
    • 1970-01-01
    • 2014-12-26
    相关资源
    最近更新 更多