【问题标题】:Pointer Pointer leads to Segmentation Fault in C指针指针导致 C 中的分段错误
【发布时间】:2021-05-25 22:07:15
【问题描述】:

为什么我可以创建一个指针数组并取消引用它的(指针)元素。

int a = 1;
int* arr[1];

arr[0] = &a;

但不能对指针做同样的事情:

int** arr2;
arr2[0] = &a;
--> Seg fault

【问题讨论】:

  • 您没有在指针指向的地方分配任何内存并且指针未初始化,因此这是未定义的行为。
  • 当你创建一个数组时,内存是隐式分配在栈上的,所以你可以立即访问它。当你想使用指针时,你需要使用arr2 = malloc(sizeof(int*))自己分配内存。

标签: arrays c pointers segmentation-fault pointer-to-pointer


【解决方案1】:

int** arr2;

你没有初始化这个指针。访问它是未定义的行为,并且可能/将导致崩溃。

要初始化使用int** arr2 = malloc(<someSize> * sizeof(*arr2)) 之类的东西。 (PS:malloc可能会返回NULL,而你必须使用free来返回内存。

【讨论】:

  • 谢谢!指针arr2 是否还存储在堆栈中?只指向我的 int 指针将被存储的堆......?
  • 没有。它在堆上
  • @ChiefHan 如果变量int** arr2;是函数内部的局部变量,则指针变量本身将在堆栈上,即存储malloc返回的地址的内存位置。指针指向将存储分配给数组元素的数据的堆。
【解决方案2】:

从第一部分开始

int a = 1;
int* arr[1];
arr[0] = &a;

所以aintarr 是什么?它是int*[],一个指向int 的指针数组。所以第一个也是唯一的元素arr[0] 是一个指向int 的指针,通常给它分配一个int 的地址。编译器对此没问题,因为运算符& --- Address of --- 将int a 的地址分配给指向intarr[0] 的指针。

从第二部分开始

    int** arr2;
    arr2[0] = &a;

arr2是什么?它是int**,一个指向int的指针。

  • arr2int**
  • 所以*arr2int*,一个指向int 的指针
  • **arrint

arr2不是什么? 不是数组,所以你不能像arr[0]那样写。

你可以写什么

arr2int**,所以在第一种情况下,它可以获得指向int 的指针的地址。在第一部分中你有一个数组。所以你肯定会写

    arr2 = &arr[0];

由于& 将提取指针的地址,而arr[0] 是指向int 的指针。而arr2就是int**,一个指向int的指针。

查看输出

toninho@DSK-2009:~/projects/um$ gcc -o tst -Wall -std=c17 pp.c
toninho@DSK-2009:~/projects/um$ ./tst
*arr[0] = 1 and **arr2 = 1
toninho@DSK-2009:~/projects/um$ 

这段代码

#include <stdio.h>

int main()
{
    int     a = 1;
    int*    arr[1]; // so arr is what? int*[]

    arr[0] = &a;

    int**   arr2; // arr2 is what? int**
    //arr2[0] = &a;

    arr2 = &arr[0];

    printf("*arr[0] = %d and **arr2 = %d\n",
        *arr[0], **arr2 );
    return 0;
};

【讨论】:

  • 为什么我不能写arr2[0]?由于x[y] == *(x + y),我们将得到*(arr2 + 0) == *arr2。正如你所说:*arr2int*。我认为问题是(如前面的评论所述)我试图取消引用某种保留的内存,因为我没有初始化我的 int** --> 分段错误
  • 阅读我最后发布的代码并进行比较。 arr2 是 int 所以它必须,正如我告诉你的,指向一个指针。你可以像我展示的那样,使用 arr2 = &arr[0]。 arr2 是 int** 不是数组。您阅读全文了吗?
  • 你运行了我在你机器上发布的程序吗?与您的代码相比?
  • 嗯,你确实没有初始化arr2。你尝试了错误的方式。我向你展示了一种合法的方式。当然你可以写*arr2 = malloc(sizeof(int)),然后给它赋值。然后在最后释放()它。但这不是重点。关键是要了解这样做的机制以及是什么,例如 int*[] 和 int**。
猜你喜欢
  • 2018-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-08
  • 1970-01-01
  • 2013-07-26
相关资源
最近更新 更多