1

以下简单示例在尝试访问minside的第一个元素时会导致分段错误main

为什么会这样?

如何修复它,但仍保持代码的整体结构相同?

谢谢。

#include <stdio.h>
#include <stdlib.h>

double *array(int cols) {
  return malloc(cols*sizeof(double));
}

void create_and_modify_array(double *m) {
  m = array(10);
  m[0] = 123;
}

void main() {
  double *m;
  create_and_modify_array(m);
  printf("%f\n", m[0]);
}
4

3 回答 3

6

这里的问题是 C 总是按值传递。按值传递意味着函数参数是调用它们的变量的副本。这意味着当你这样做时:

m = array(10);

在里面create_and_modify_array(double *m),你只是改变函数的本地副本m点的位置。m来自 main 方法的指针不受影响(并且保持未初始化,因此崩溃)。

要解决此问题,您可以将指针传递给main()'m指针:

void create_and_modify_array(double **m) {
  *m = array(10); // change the pointer that `m` points to
  (*m)[0] = 123;  // assign something to the first element of what `m` points to
}

main()并将's的地址传入m

void main() {
  double *m; // make a pointer to a double
  create_and_modify_array(&m); // pass a pointer to the pointer to the double
                               // or, in alternative wording: 
                               // pass the address of the pointer to the double
于 2013-02-14T00:28:44.917 回答
2

因为在中创建的指针与在中create_and_modify_array声明和使用的地址不同main()。你可以这样做

double *create_and_modify_array(double *m) {
  m = array(10);
  m[0] = 123;
  return m;
}

void main() {
  double *m = create_and_modify_array(m);
  printf("%f\n", m[0]);
  free (m);
}
于 2013-02-14T00:28:47.433 回答
1

它是段错误,因为 m insidecreate_and_modify_array是一个局部变量,所以 m insidemain仍然是未初始化的。

更明确地说,代码流是:

开头main m是一个随机的、未分配的内存地址。然后它create_and_modify_array用那个内存地址调用。在内部创建create_and_modify_array了一个名为的新变量m,它具有传入的随机、未分配的内存地址。然后您调用array并将其中的变量分配给您分配的内存。mcreate_and_modify_array

问题是该值mnever 被传递回min main

为此,您需要将指向 main 的指针传递mcreate_and_modify_array

void create_and_modify_array (double **m) {
    double *tmp = array(10);
    tmp[0] = 123;
    *m = tmp; // This passes the value of tmp back to the main function.
              // As m in this function is actually the address of m in main
              // this line means put tmp into the thing that is at this address
}

void main () {
    double *m;
    create_and_modify_array (&m); // This passes the address of the variable m
                                  // into create_and_modify_array
    printf ("%f\n", m[0]);
}
于 2013-02-14T00:35:29.113 回答