请解释(输出的原因)运行这两段代码的结果请解释一下他们的区别有两个版本的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/

10-12 14:55