C 为什么这个变量在返回语句后会改变?

C 为什么这个变量在返回语句后会改变?,c,function,variables,return,C,Function,Variables,Return,我有一个带有签名的函数: int exe(int stack[][STACKSIZE], int sp[], int reg[][REGISTERSIZE], int next_instruct[], int next_inst[], int cur_proc, int *terminate); 它有最后两行: printf("TWO cur_proc: %d\n",cur_proc); return NORMAL; 这就是所谓的: printf("ONE cur_proc:

我有一个带有签名的函数:

int exe(int stack[][STACKSIZE], int sp[], int reg[][REGISTERSIZE], int next_instruct[],
        int next_inst[], int cur_proc, int *terminate);
它有最后两行:

printf("TWO cur_proc: %d\n",cur_proc);
return NORMAL;
这就是所谓的:

printf("ONE cur_proc: %d\n",cur_proc);
msg = exe(stack,sp,reg, next_instruct, next_instruct, cur_proc, &terminate);
printf("THREE cur_proc: %d\n",cur_proc);
我正在传递
cur\u proc
,它被认为是
exe()
内部的一个“只读”(通过值传递并不重要)变量。在
exe()
中执行我的任务

我的输出是:

ONE cur_proc: 1
TWO cur_proc: 1
THREE cur_proc: -1
这让我很困惑,因为我看不出有任何理由可以用一个负数覆盖它


出现这种奇怪行为的可能原因是什么?

如果
exe
函数中的代码将数据写入传入的某个数组中的无效位置,堆栈可能会损坏,这可能会更改堆栈上方局部变量的值(以及其他不好的事情)

从函数的角度考虑变量的只读性质,要么发生了这种情况,要么另一个线程正在修改cur_proc的值——如果不处理线程,则前者更可能发生


大多数调试器允许您在“更改内存中特定地址的值”上放置断点。如果您获得cur_proc的地址,并在该地址的值发生变化时中断,您应该找到罪魁祸首。

您可能在其中一个数组的边界之外写入

在函数内部,您看到的是调用函数中变量的副本,而不是原始变量。因此,函数中的
printf()
不会告诉您调用函数中的值何时损坏

看看传递的数组,函数中被修改的数组是最可能的罪魁祸首,或者说是被修改的数组。由于没有一个数组是const限定的,所以很难说修改了哪些数组,但有些数组可能超出了范围


如果要跟踪调用函数中对
cur\u-proc
的更改何时从被调用函数内部发生,请将指向
cur\u-proc
的指针以及或代替值传递到函数中,并通过指针打印值。

这也是我的第一个想法,但我以前从未见过。我将如何调试它?(顺便说一句,这是非线程的)大多数调试器允许您在“更改内存中特定地址的值”上放置断点。如果您获得cur_proc的地址,并且在该地址的值发生变化时中断,您应该找到您的罪魁祸首……话虽如此,Jonathan Leffler在他的回答中描述了一种技术含量较低且更简单的方法,即如果您不知道如何使用调试器,那么这种方法非常值得考虑。另外,您是否知道学习gdb或类似(命令行调试器)的好资源?一种查看cur_proc何时更改其值的简单方法是在参数声明前面加上const。编译器将在您更改其值的确切位置抛出错误。我先尝试了。没有错误,因为据编译器所知,它没有被更改。然后使用运行程序。程序的另一部分可能正在腐蚀堆。确实如此。常数设置得太小了,就是这样。堆栈函数正在其边界之外写入。看着指向cur_proc的指针,它被清除了。