我有一个带签名的功能:
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_proc
exe()
被认为是“只读”(并不是值得通过值传递)变量exe()
。把我的东西放在ONE cur_proc: 1
TWO cur_proc: 1
THREE cur_proc: -1
里面。
我的输出是:
{{1}}
这对我来说非常困惑,因为我看不出有任何理由认为这可能被否定的覆盖。
这种奇怪行为的可能原因是什么?
答案 0 :(得分:4)
你可能正在写一个数组的边界之外。
在函数内部,您正在查看调用函数中的变量副本,而不是原始变量。因此,函数内的printf()
不会告诉您调用函数中值何时被破坏。
查看传递的数组,并且在函数内修改的数组是最可能的罪魁祸首 - 或者是被修改的数组。由于没有一个数组是const限定的,很难说哪些是被修改的,但有些东西可能会超出界限。
如果要跟踪调用函数中cur_proc
的更改何时从被调用函数内部发生,请将指向cur_proc
的指针传递给函数 - 以及代替值 - 并通过指针打印该值。
答案 1 :(得分:3)
如果exe
函数中的代码将数据写入传入的其中一个数组中的无效位置,则堆栈可能会损坏,这可能会更改堆栈中较高位置的局部变量的值(其中)其他坏事)。
从函数的角度考虑变量的只读性质,要么发生这种情况,要么另一个线程正在修改cur_proc的值 - 如果你没有摆弄线程,前者似乎更有可能。
大多数调试器允许您在“更改内存中特定地址的值”上放置断点。如果你得到cur_proc的地址并在这个地址的值发生变化时中断你应该找到你的罪魁祸首。