C 正在从结构**-SEGFULT初始化结构
我正在尝试初始化一个结构,从指针到指针。我用一个init函数来做这个。然而,这会产生一个错误。 我试图从中初始化的指针是在数组中定义的。当阵列的大小设置为1时,segfault不会发生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
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)
原始代码有几处错误:
#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
应该做什么?