我在C中遇到过一个我以前从未遇到的奇怪问题.我已将其缩小到以下非常简单的片段.
变量是全局变量和类型:
int cpd;
int nPart;
Run Code Online (Sandbox Code Playgroud)
这里是相关的代码片段,我逐渐将其删除到产生问题所需的最低限度:
printf("\ncpd1: %d\n",cpd);
int p;
for(p=1;p<=nPart;p++)
{
printf("\ncpd2: %d\n",cpd); exit(0);
}
Run Code Online (Sandbox Code Playgroud)
...我得到的输出是这样的:
cpd1: 17
cpd2: 0
Run Code Online (Sandbox Code Playgroud)
这怎么可能?!cpd还没有被重新分配,没有调用任何函数......但它改变了吗?怎么样?!?!
这已经让我慢慢疯了一段时间了......所以任何想法?
谢谢你的时间,本.
编辑:当我从gcc的makefile参数中删除-02时,打印语句告诉我cpd = 0!
编辑:好的,我刚刚发现一个全局声明的变量,初始化为4.0,然后从未修改过的变量现在显然是1.51086e-311 ...某处出了点问题......
编辑:已解决!:我有一个1000大小的数组,需要超过4000,并试图写这个是破坏它周围的记忆.事实是,这些数组不会在那些打印语句附近的任何地方被访问,但它可以在相同的函数中访问,但更早(大函数!).打印语句之间的奇怪差异必须是使用-O2的一些奇怪的假象,因为没有-O2,两个打印的cpd打印损坏的版本.谢谢大家,没有你的帮助,我不会这样做!
Han*_*ant 15
由于缓冲区溢出导致的堆栈帧损坏通常是对此的解释.这是一个例子:
#include <stdio.h>
#include <string.h>
int main()
{
int cpd;
char msg[4];
cpd = 17;
printf("%d\n", cpd);
strcpy(msg, "Oops");
printf("%d\n", cpd);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
17
0
Run Code Online (Sandbox Code Playgroud)
"msg"字符串缓冲区太短一个字符,字符串终止符会覆盖"cpd"的值.
找到原因的最佳方法是使用调试器的数据断点功能.在函数入口点上设置常规断点.然后找到"cpd"变量的地址,并在其上设置一个字节大小的数据断点.一旦cpd值改变,调试器就会停止.
请注意,这不一定适用于优化代码,"cpd"值可能存储在寄存器中.这是另一种可能的解释,为什么它在不同的陈述中的价值不同.
我能想到的唯一可能的原因是你声明了另一个本地int cpd变量.作为一个例子,我拿了你的代码并稍微修改它以添加另一个int cpd声明并保持未初始化:
注意我必须设置nPart = 1所以for循环执行至少一次
#include <stdio.h>
int cpd;
int nPart = 1;
int main (int argc, char ** argv)
{
printf("\ncpd1: %d\n",cpd);
int cpd;
int p;
for(p=1;p<=nPart;p++)
{
printf("\ncpd2: %d\n",cpd);
break;
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行它时,我得到以下输出:
cpd1:0
cpd2:2130567168
正如预期的那样,全局变量cpd为0,本地cpd未初始化,几乎可以是任何32位值.
| 归档时间: |
|
| 查看次数: |
7287 次 |
| 最近记录: |