Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 正在从结构**-SEGFULT初始化结构_C_Struct_Segmentation Fault - Fatal编程技术网

C 正在从结构**-SEGFULT初始化结构

C 正在从结构**-SEGFULT初始化结构,c,struct,segmentation-fault,C,Struct,Segmentation Fault,我正在尝试初始化一个结构,从指针到指针。我用一个init函数来做这个。然而,这会产生一个错误。 我试图从中初始化的指针是在数组中定义的。当阵列的大小设置为1时,segfault不会发生 typedef struct{ int a; }myStruct; void init_struct(myStruct** s){ (*s)->a=10; } void fun(myStruct** sp){ init_struct(sp); } int main(){ myStruc

我正在尝试初始化一个结构,从指针到指针。我用一个init函数来做这个。然而,这会产生一个错误。 我试图从中初始化的指针是在数组中定义的。当阵列的大小设置为1时,segfault不会发生

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时,为什么这样可以?(我假设未定义的行为)


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

使用
myStruct*s[2]
,您会为指向
myStruct
的两个指针保留内存,但您不会初始化这些指针以使它们指向有效的
myStruct
-对象。取消引用这样一个(未初始化的)指针会产生未定义的行为(很可能是segfault)

像这样的命令

s[0] = malloc(sizeof(myStruct));

应该至少为第一个指针解决这个问题。

发布的代码实际上无法为实际的结构实例分配任何内存


因此,尝试写入指针指向应用程序不拥有的内存的位置时,请注意,
myStruct*s[2]
只是声明了一个由2个单元化指针组成的数组(指向myStruct类型的结构)

指针很可能指向无效内存,您在
init_struct
中通过以下表达式访问该内存:
(*s)->a
(如果您还不知道,它相当于
s[0]->

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

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

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

s[0]->a = 10;
请注意,除非同时释放分配的内存,否则应用程序将出现内存泄漏:

free(s[0]);
此外,您可以使用非常有用的工具valgrind检查错误,该工具应提供以下输出:

$ valgrind ./a.out
==12820== Memcheck, a memory error detector
==12820== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==12820== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==12820== Command: ./a.out
==12820== 
==12820== 
==12820== HEAP SUMMARY:
==12820==     in use at exit: 0 bytes in 0 blocks
==12820==   total heap usage: 1 allocs, 1 frees, 8 bytes allocated
==12820== 
==12820== All heap blocks were freed -- no leaks are possible
==12820== 
==12820== For counts of detected and suppressed errors, rerun with: -v
==12820== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

原始代码有几处错误:

  • 它从未实际初始化任何存储(主要问题)

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

  • “fun()”似乎多少有些无关紧要

  • 如果您有一个“分配”函数,您可能还需要一个相应的“空闲”函数

  • 建议的修改:

    #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结构myStruct{
    INTA;
    }我的结构;
    myStruct\u t**init\u struct\u数组(int nelms){
    int i;
    myStruct\u t**sArray=malloc(sizeof(myStruct\u t*)*nelms);
    对于(i=0;ia=i;
    /*您可能需要的任何其他初始化都会转到此处*/
    }
    返回沙雷;
    }
    无空结构数组(myStruct\t**sArray,int-nelms){
    int i;
    对于(i=0;ia=%d...n”,i,s[i]->a);
    自由结构数组(s,n);
    }
    

    您可能还希望将您的“typedef”以及“init_struct_array()”、“free_struct_array”和任何其他相关“操作”的原型放在它们自己的.h头文件中。

    如果您无法更改“main”的内容。你可以试试

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

    fun
    应该做什么?