为什么我在初始化结构时会遇到段错误?

lin*_*usz 1 c malloc struct segmentation-fault

搜索了一个小时左右.我想我最好在这里发布这个问题.

我简化了代码.段错误在功能中initMyStruct.

#include "stdlib.h"

typedef struct {
        int * arr1;
        int * arr2;
} myStruct;

void allocMyStruct (myStruct * a, int num) {
        a = malloc(sizeof(myStruct));
        a->arr1 = malloc(10*sizeof(int));
        a->arr2 = malloc(10*num*sizeof(int));
}
void initMyStruct (myStruct * a, int num) {
        int i;
        for (i = 0; i < 10; i++)     a->arr1[i]  =  0;
        for (i = 0; i < 10*num; i++) a->arr2[i]  = -1;
}
void freeMyStruct (myStruct * a, int num) {
        int i;
        for (i = 0; i < 10; i++)     free(a->arr1);
        for (i = 0; i < 10*num; i++) free(a->arr2);
        free(a);
}
int main (void) {
        int num = 3;
        myStruct * a;
        allocMyStruct (a, num);
        initMyStruct  (a, num);
        freeMyStruct  (a, num);
        return 1;
}
Run Code Online (Sandbox Code Playgroud)

unw*_*ind 5

因为您没有将指针保留到新分配的内存,而是使用未初始化的指针并获取未定义的行为.

您将a变量传递给allocMyStruct(),但该调用(与所有其他调用一样)按值,因此在函数内分配给它的新值不会影响ain 的值main().

更改它,以便allocMyStruct()要么返回新的指针值,或者需要一个指针的指针.我更喜欢前者,它更干净,使用函数返回值通常会导致更好的代码:

myStruct * allocMyStruct(int num)
{
  myStruct *p;

  if((p = malloc(sizeof *p +
                 10 * sizeof *p->arr1 +
                 10 * num * sizeof *p->arr2)) != NULL)
  {
    p->arr1 = (int *) (p + 1);
    p->arr2 = p->arr1 + 10;
  }
  return p;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码还简化了内存分配,在一个大malloc()调用中完成所有操作,然后将其"切片"为您实际需要的三个部分.

如果顺序的大小arr1总是10,那么动态分配是没有意义的,它应该只int arr1[10];在struct声明中.