从struct **初始化struct-segfault

时间:2018-11-05 22:42:22

标签: c struct segmentation-fault

我正在尝试初始化从指针到指针的结构。我正在使用init函数。但是,这会造成段错误。 我试图从中初始化的指针是在数组中定义的。将数组的大小设置为1时,不会发生段错误。

typedef struct{
  int a;
}myStruct;

void init_struct(myStruct** s){
  (*s)->a=10;
}

void fun(myStruct** sp){
  init_struct(sp);
}

int main(){
  myStruct* s[2];
  fun(&s[0]);
}

我知道这是因为我不应该访问内存,但是为什么在这种情况下我不允许访问? 当数组的大小为1时为什么可以? (我假设行为不确定)

这是学校作业的简化部分,因此不允许我更改“主要”的内容。

5 个答案:

答案 0 :(得分:3)

使用myStruct* s[2],您可以为两个指向myStruct的指针保留内存,但是您不会初始化这些指针以使其指向有效的myStruct对象。取消引用此类(未初始化的)指针会产生未定义的行为(很可能发生段错误)。

类似

的命令
s[0] = malloc(sizeof(myStruct));

至少应针对第一个指针解决此问题。

答案 1 :(得分:2)

如果您不能更改“ main”的内容。你可以尝试

void init_struct(myStruct** s) {
    (*s) = malloc(sizeof(myStruct));
    (*s)->a=10
}

答案 2 :(得分:1)

发布的代码无法实际为实际的struct实例分配任何内存。

因此,尝试写指针指向的位置是写入应用程序不拥有的内存

答案 3 :(得分:1)

请注意,myStruct * s[2]只是声明了一个2个单位初始化的指针的数组(指向myStruct类型的结构)。

指针很可能指向无效的内存,您可以通过以下表达式在init_struct中进行访问:(*s)->a(如果您还不知道,则等效于{{ 1}})。

您可以通过分配适合该结构的内存来修复无效的内存访问:

s[0]->

您还应该检查s[0] = malloc(sizeof s[0]); 是否成功分配了内存:

malloc

然后,您可以自由地写入刚分配的if (s[0] == NULL) { return; // error } 的未初始化成员:

myStruct

请注意,除非您还释放分配的内存,否则应用程序将发生内存泄漏:

s[0]->a = 10;

此外,您可以使用非常有用的工具valgrind检查错误,该工具应该为您提供以下输出:

free(s[0]);

答案 4 :(得分:1)

原始代码有几处错误:

  1. 它从未真正初始化任何存储(主要问题)

  2. 它被硬编码为“ 2个元素”

  3. “ fun()”或多或少无关紧要

  4. 如果您具有“分配”功能,则可能还需要相应的“免费”

建议的更改

#include <stdio.h>
#include <malloc.h>

typedef struct myStruct {
  int a;
} myStruct_t;

myStruct_t** init_struct_array(int nelms){
  int i;
  myStruct_t **sArray = malloc(sizeof (myStruct_t*)*nelms);
  for (i=0; i < nelms; i++) {
    sArray[i] = malloc(sizeof (myStruct_t));
    sArray[i]->a = i;
    /* Any other initialization you might want goes here... */
  }
  return sArray;
}

void free_struct_array(myStruct_t **sArray, int nelms){
  int i;
  for (i=0; i < nelms; i++) {
    free(sArray[i]);
  }
  free(sArray);
}

int main(){
  int i, n = 2;
  myStruct_t** s = init_struct_array(n);
  /* Use your array here... */
  for (i=0; i < n; i++) 
    printf ("s[%d]->a=%d...\n", i, s[i]->a);
  free_struct_array(s, n);
}

您可能还希望将“ typedef”以及“ init_struct_array()”,“ free_struct_array”以及所有其他相关“操作”的原型放到自己的.h头文件中。