【问题标题】:Value of local static variable changes between function calls [closed]函数调用之间局部静态变量的值变化[关闭]
【发布时间】:2018-12-11 09:54:48
【问题描述】:

我在一个定期调用的函数中声明了一个静态变量。我知道将变量声明为静态可以使其在程序生命周期内有效,而无需再次重新声明。当然,因为它是本地的,所以只能通过它的功能来修改。

奇怪的是,在调试代码时,函数执行完毕,在离开函数之前,我确定变量的值为0。在下一个函数调用中,变量的值在执行函数的任何行之前递增256。如果变量的值在离开函数之前为10,则在下一次调用时变为266。这种行为是持久的。

什么会导致局部静态变量的值在函数调用之间发生变化?

很遗憾,我无法提交重现问题的代码 sn-p。

【问题讨论】:

  • 我猜你代码中的其他地方有缓冲区溢出(覆盖warningBounce
  • 我已经在一个测试程序中猛击了你的代码,它在这里工作正常,所以我支持@pmg 的建议,即某些东西正在覆盖 var。用 valgrind 检查一下。
  • @Salahuddin 我们告诉你为什么 var 可能会改变。请检查一下。由于您没有提供可重现的问题,我们只能猜测。我已将您的代码扩展为一个完整的程序,其中 getVoltage 返回一个随机变量并执行所有内容 100 次。它对我有用...
  • 好的。我会努力的。谢谢
  • 您显示的代码没有做任何有用的事情。 warningBounce 永远不会在函数内部读取,也无法在函数外部读取。

标签: c variables static


【解决方案1】:

什么会导致局部静态变量的值在函数调用之间发生变化?

一个可能的原因是代码的另一部分中的错误已写入存储静态变量的内存位置。

看看这段代码:

void bar()
{
  static char y[2];
  y[0] = '4';
  y[1] = '2';
  printf("BAR y=%c%c  location of y is %p\n", y[0], y[1], (void*)y);

  y[2] = 0; // error! writing out of bounds
  y[3] = 1; // error! writing out of bounds
}

void foo()
{
  static uint16_t x = 0;
  printf("FOO x=%"PRIu16"  location of x is %p\n", x, (void*)&x);
  ++x;
}

int main( int argc, char **argv ){
  foo();
  foo();
  foo();
  foo();
  foo();
  bar();
  foo();
  return 0;
}

您会注意到函数bar 包含一个错误,即它写入超出了为y 分配的内存。

在我的系统上运行这段代码:

FOO x=0  location of x is 0x100407002
FOO x=1  location of x is 0x100407002
FOO x=2  location of x is 0x100407002
FOO x=3  location of x is 0x100407002
FOO x=4  location of x is 0x100407002
BAR y=42  location of y is 0x100407000
FOO x=256  location of x is 0x100407002
    ^^^^^
    oh dear, x has changed...

所以在我的系统上,静态变量 x 被放置在静态变量 y 之后。因此,当bar 被调用时,x 的值会因为bar 中的错误而被覆盖。

注意:在其他系统上结果可能不同。

因此建议是:在函数的两次调用之间执行的代码中查找缓冲区溢出。

【讨论】:

    【解决方案2】:

    如 cmets 和其他答案所述,这绝对是一个错误,很可能是代码另一部分的缓冲区溢出。

    要查找代码的何时以及哪一部分修改了您的静态局部变量,您可以使用内存断点(或数据断点)。开始调试,并在第一个函数调用上为变量的大小设置一个内存断点。现在,当罪魁祸首代码修改此内存区域(即您的静态变量)时,代码将中断。

    在 Visual Studio 中,我认为它被称为数据断点。

    gdb 通过watch 命令也具有此功能。在这里查看如何:Can I set a breakpoint on 'memory access' in GDB?

    【讨论】:

      猜你喜欢
      • 2013-09-29
      • 2016-07-26
      • 1970-01-01
      • 1970-01-01
      • 2019-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多