C程序打印意外输出



我有下面的C程序:

#include <stdio.h>
void setArr(int, int);
int *arr[10]; // array of 10 int pointers
int main(int argc, char *argv[])
{
int i;
setArr(0, -10);
setArr(1, 100);
setArr(2, 200);
setArr(3, 300);
setArr(4, 400);
for (i = 0; i < 5; i++)
printf("arr[%d] -*-> %d %dn", i, *arr[i], **(arr + i)); /* should be -10,100, 200,300,400 */
return 0;
}
/* set arr[index], which is a pointer, to point to an integer of value v */
void setArr(int index, int v)
{
int i = v;
arr[index] = &i;
}

输出如下:

arr[0] -*-> 400 400
arr[1] -*-> 400 400
arr[2] -*-> 400 400
arr[3] -*-> 400 400
arr[4] -*-> 400 400

我所理解的是,arr中的每个元素都是一个指针,它将指向在函数内创建的变量i的位置。

我不确定它如何始终如一地返回400总是
什么可能是这种输出的原因以及如何纠正它?

函数内部的int i = v;定义自动为i保留内存。当函数执行结束时,内存预留将被释放。

一旦内存预留被释放,C标准不保证任何指向内存的指针的值,你不应该使用这些值。

每次调用setArr时,内存被保留,然后释放。一个常见的结果是,在保留、释放、保留、释放等操作中使用了相同的内存,并且指针似乎指向相同的位置。然后将arr的每个元素设置为指向相同的位置。但是,编译器的优化和其他操作可能会产生其他行为。

当然,这个位置一次只能保存一个值,所以在调用setArr之后只能看到一个值。

你的代码没有意义。

对于初学者来说,在C语言中,像i这样的局部变量的地址一旦包含它的函数退出就无效了。

这意味着数组中的所有指针在setArr之外都无效。

第二,C编译器通常在堆栈上分配局部变量,这意味着i很可能在每次调用setArr时都位于相同的地址,因此您看到的输出是完全合乎逻辑的。

i的值在每次调用时都会被覆盖,并且由于您在最后一次调用setArr之后立即打印它,因此内存虽然在技术上是空闲的,但尚未被覆盖。

因此,幸运的是,您可以在所有printf调用中看到最后一次调用setArr的结果。

最新更新