【问题标题】:Why does one way of malloc seg fault but another doesn't? [duplicate]为什么 malloc 段错误的一种方式,而另一种没有? [复制]
【发布时间】:2017-02-06 21:35:20
【问题描述】:

如果我有一个 int 数组:

int *array;

array = malloc(5 * sizeof(int));

然后我像上面一样对其进行 malloc,然后我可以访问它并为其设置值。一切都很好。

但是如果我创建该 int 指针并将其传递给一个函数并在函数中进行 malloc inside,我将无法访问/设置数组的值 除非我将它作为指向指针的指针传递给数组?

some_void_function(int *array) {
    array = malloc(5 * sizeof(int))
}

int *array;
some_void_function(array);

*(array + 3) = 5; // DOES NOT WORK

要修复它,我可以让数组接受 (int **array) 作为参数并传入指针的地址(因此是指向指针的指针),取消引用它,然后用 malloc 分配它:

some_void_function(int **array) {
    *array = malloc(5 * sizeof(int))
}

int *array;
some_void_function(&array);

*(array + 3) = 5; // WORKS 

有人可以向我解释一下吗?在这两种情况下我不是在做同样的事情吗?传递地址然后只是取消引用它与首先传递单个指针是一样的吗?

【问题讨论】:

  • 如果不是,怎么可能是一样的呢?通过调用some_void_function(array);,您不会修改array,因为它是按值传递的。

标签: c arrays pointers


【解决方案1】:

指针是保存地址的变量。但是它们与所有其他类型的变量都遵循相同的规则,这意味着它们是按值传递的。

void some_void_function(int *array) {
    array = malloc(5 * sizeof(int))
}

arraysome_void_function 的本地变量,您对其值所做的任何更改都不会反映在从中复制它的指针中。

要修改调用代码中的变量(包括指针),您有两种选择:

  1. 按指针传递,即指向你的指针的指针:

    void some_void_function(int **array) {
      *array = malloc(5 * sizeof(int))
    }
    
  2. 返回你分配的地址并赋值给指针:

    int* some_allocating_function() {
      return malloc(5 * sizeof(int))
    }
    //...
    int *array = some_allocating_function();
    

【讨论】:

  • 明确一点,pointer 的本地副本已创建,对吗?因此,当我在函数内部执行 malloc 时,我实际上只是 malloc'ing 到另一个指针(本地指针)而不是我期望 malloc 到的那个?
  • @Zhinkk - 合二为一:)
  • 对不起,这给我带来了另一个困惑:如果指针是按值传递的,为什么会这样? void test(int *array) { *(array) = 10 } 在 main 中,数组已更改。但是你不是说指针是按值传递的吗?
  • @Zhinkk - 您不传递数组,而是传递int 的地址。如果它是一个有效的地址,它可以用来修改那个int。同样,如果我传递int *地址(表示类型为int **),我可以使用它来修改int *
  • 完美!谢谢你这么清楚的解释。
【解决方案2】:

那是因为 c 按值传递参数

some_void_function(int *array) {
    array = malloc(5 * sizeof(int))
}

这段代码只是修改了array的本地副本,它不会改变array的调用者副本

这段代码

some_void_function(int **array) {
    *array = malloc(5 * sizeof(int))
}

传入调用者数组的地址,这使您可以脱离函数并更改调用者数组指针

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-04
    • 1970-01-01
    • 1970-01-01
    • 2021-01-03
    • 1970-01-01
    • 2017-04-27
    • 1970-01-01
    相关资源
    最近更新 更多