[英]Initializing struct from struct** - segfault
我正在尝试初始化一个结构,从一个指针到一个指针。 我正在使用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时为什么可以? (我假设行为不确定)
这是学校作业的简化部分,因此不允许我更改“主要”的内容。
使用myStruct* s[2]
,您可以为两个指向myStruct
指针保留内存,但是不初始化这些指针是为了使它们指向有效的myStruct
对象。 然后,取消引用此类(未初始化的)指针会产生未定义的行为(很有可能发生段错误)。
像这样的命令
s[0] = malloc(sizeof(myStruct));
应该至少针对第一个指针解决此问题。
如果您不能更改“ main”的内容。 你可以试试
void init_struct(myStruct** s) {
(*s) = malloc(sizeof(myStruct));
(*s)->a=10
}
发布的代码无法实际为实际的struct实例分配任何内存。
因此,尝试编写指针指向的位置正在写入应用程序不拥有的内存
请注意, 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”以及“ init_struct_array()”,“ free_struct_array”以及所有其他相关“操作”的原型放到自己的.h头文件中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.