【问题标题】:Uninitialized variables - Stack examination未初始化的变量 - 堆栈检查
【发布时间】:2014-03-21 18:10:54
【问题描述】:

假设我在C 中编写此代码。 如果我有一个未初始化的变量number,我不知道它的值是什么。但是...

什么是随机值?我在内存转储中有什么?是不是因为尝试读取地址却没有出来?

我尝试调试我的程序,但我还是个新手,所以我很容易迷路。 另外,如果我添加一个zerowillcome 变量(参见代码2),我的number 值将不再是随机的:它将是0。我不明白为什么会发生这种情况,但我认为这与将顺序变量推入堆栈有关。我对吗?有人可以一步一步地描绘我到底发生了什么吗?

PS:那些其他变量在那里,因为这是其他代码的 sn-p,所以我不知道删除它们是否能够改变应用程序行为:我的注意力被由添加zerowillcome 变量。

代码 1:

int main (int argc, char *argv[])
{
    int number, var1, var2, tmp, tmp2;
        printf("number: %d", number); // <- insert random number here
        return 0;
}
    

代码 2:

int main (int argc, char *argv[])
{
    int number, var1, var2, tmp, tmp2, zerowillcome;
        printf("number: %d", number); // <- 0 !!!
        return 0;
}

【问题讨论】:

  • 您获得的任何结果不仅是未定义的,而且它们被称为未定义,因为它们将来可能会发生变化。知道今天的价值是如何到达那里的,明天它可能不再存在时,这并不是很有成效。

标签: c debugging stack uninitialized-constant


【解决方案1】:

那个随机值是什么?

通常,它是之前某个函数调用在该内存位置留下的任何值。

当您调用一个函数时,首先发生的事情之一是堆栈指针递增以保留该函数的返回地址、返回值和局部变量所需的空间。当函数退出时,堆栈指针减少相同的量。在这两者之间,该内存被函数用来存储数据。在函数返回并调用其他函数后,会发生同样的事情,并且可能会使用相同的内存。如果该函数未将其变量初始化为某个已知值,则变量将碰巧具有前一个函数留在堆栈中的任何内容。

不过,您不应该关心这个,当然也不应该依赖它。初始化变量的值是未定义的,所以它可以是anything。例如,编译器可以插入指令来清除函数在函数调用之前或之后使用的所有堆栈内存。或者它可以将内存设置为字符串“不要使用未初始化的变量!”或其他任何东西。唯一合理的方法是确保在读取变量之前将一些值写入变量(即初始化它们)。

【讨论】:

  • 另请注意,在某些系统上,内核可能会使用未分配的堆栈内存在上下文切换中保存状态,或者可能使用它来运行信号处理程序。两者都会破坏堆栈指针下方内存中的数据,这种方式可以在程序中的任何点从外部触发,并且完全超出进程的控制.
【解决方案2】:

这是未定义的行为,您的变量在声明时未初始化。

【讨论】:

  • 那个数字是多少?它是十六进制表示吗?我在内存转储中看到了什么?
  • @Krishath 未定义的行为意味着您的编译器可以采取任何路线,因此您有一个格式错误的程序(在这种情况下编译)。这只是垃圾。
  • @Krishath 如果您使用的是 MSVC,它很可能是十六进制 0xCCCCCCCC,MSVC 程序会自动用 0xCC 填充未初始化的堆栈。
  • @Aean 您还应该提醒一下,MSVC 中的 C 支持不是很好,这不是编写代码的好方法。如果向 MSVC 抛出未定义的行为,它不会生成更好的代码。
  • @user2485710 显然是的。但 0xCC 有时有助于调试。
猜你喜欢
  • 2014-12-15
  • 1970-01-01
  • 2019-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-28
  • 2019-01-01
  • 2016-07-31
相关资源
最近更新 更多