请解释(输出的原因)运行这两段代码的结果请解释一下他们的区别有两个版本的setArr(int, int)
如下所述。。。
#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, 0);
setArr(1, 100);
setArr(2, 200);
setArr(3, 300);
setArr(4, 400);
for (i = 0; i < 5; i++)
printf("arr[%d]: %d\n", i, *arr[i]); /* should be 0,100, 200,300,400 */
return 0;
}
setArr
的版本A版
void setArr(int index, int v) {
int i = v;
*arr[index] = i;
}
输出:
Segmentation fault (core dumped)
版本B
void setArr(int index, int v) {
int i = v;
arr[index] = &i;
}
输出:
arr[0]:400
arr[1]:32748
arr[2]:32748
arr[3]:32748
arr[4]:32748
我假设运行版本B的值只是随机值。
我对指针还比较陌生,我对Java有一定的了解,所以请尽可能对初学者友好地解释一下:)
最佳答案
你遇到了很多未定义的行为场景,但我将解释可能发生的情况。arr
是指向整数的10个指针的数组。
int * arr[10]; // array of 10 int pointers
当声明为全局变量时,所有这些指针都将被初始化为零-因此,它是一个由10个空指针组成的数组。
因此,版本A中的这一行,正在取消对
arr[index]
中地址的引用:* arr[index] = i;
实际上是这样说的:
*(NULL) = i;
这肯定会持续崩溃。
在版本B中,您将其作为:
int i = v;
arr[index] = &i;
所以现在您可以正确地将指针分配给数组中的一个插槽然而,这个地址被分配给一个本地堆栈变量
i
,一旦函数返回,这个变量就会超出范围因此,当您在该地址打印值时,它肯定会被写在堆栈顶部的其他调用所破坏。(或者从技术上讲,这种访问超出范围的堆栈变量的内存地址的“未定义行为”)更好:
void setArr (int index, int v){
arr[index] = malloc(sizeof(int));
*arr[index] = v;
}
上面为要将该值复制到的地址分配内存。你得靠自己来释放记忆。
或者:
只需将
arr
声明为整数数组而不是指针:int arr[10];
void setArr (int index, int v){
arr[index] = v;
}
然后在
*
上正常打印。printf("arr[%d]: %d\n", i, arr[i]);
关于c - 段错误的原因与使用以下C代码返回随机值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57069392/