有从文件中读取的程序并返回结构。
struct ion_bin
{
int freq;
long height;
int amplitude;
};
//Dynamic auto allocating array
typedef struct {
struct ion_bin *array;
size_t used;
size_t size;
} Ionogram;
void freeArray(Ionogram *a); //free memory
void insertArray(Ionogram *a, struct ion_bin element); //realloc memory
void initArray(Ionogram *a, size_t initialSize); //malloc memory
Ionogram* read(int argn, char* argv[])
{
FILE* stream;
Ionogram ionogramObj;
//fill ionogram from file by initArray and insertArray
//.....
return &ionogramObj;
}
int main(int argn, char* argv[])
{
Ionogram* r = read(argn, argv);
fprintf(stderr,"Array size: %d Used %d\n",r->size, r->used); //SEGMENTATION FAULT ERROR
//int second = (*(r->array + 2)).amplitude; //YET SEGMENTATION FAULT ERROR TOO
//fprintf(stderr, "%d", second);
return 0;
}
此程序编译成功,但在运行时和调试中通过尝试获取返回结构的字段(在main方法中)触发分段错误错误(SIGSEGV)如何修复此错误?
答案 0 :(得分:4)
你犯了一个初学者错误,并返回一个指向局部变量的指针。你必须记住,一旦函数返回,局部变量就会超出范围,并且指向它的指针将变为无效。取消引用此无效指针会导致未定义的行为。
两种可能的解决方案:
malloc
为结构分配内存,并返回指向此动态分配内存的指针。方法一适用于较小的结构,如你的,但对于较大的结构效率低,因为必须复制整个结构。 (虽然这是一个浅副本,但不是深层副本。所以如果你在结构中有指针,那么只复制指针而不是它们所指向的指针。)
答案 1 :(得分:2)
您正在返回一个指向函数末尾超出范围的变量的指针。
Ionogram ionogramObj;
return &ionogramObj;
C中的未定义行为。
作为替代,malloc
函数中结构的内存并返回指向该结构的指针。在某些时候别忘了free
指针。
答案 2 :(得分:1)
在您的代码中,ionogramObj
变量是函数read()
的本地变量。一旦函数完成执行,就不存在ionogramObj
,因此,实际上返回的地址在调用者(main()
)中变为无效。
访问无效地址(指针)会调用undefined behaviour。分割错误是UB的副作用之一。
为避免这种情况,您需要返回一个寿命大于被调用函数的地址。借助指针和动态内存分配,您可以实现此目的。
查看伪代码
Ionogram* read(int argn, char* argv[])
{
FILE* stream = NULL;
Ionogram *ionogramObj = NULL; //take a pointer
ionogramObj = malloc(sizeof(*ionogramObj)); //allocate memory dynamically
if (!ionogramObj) //don't forget to check for success
//some error message, return or exit, maybe?
else
//do normal operation
//fill ionogram from file by initArray and insertArray
//.....
return ionogramObj; //return the pointer
}
此外,动态分配的内存需要free()
d以避免内存泄漏。使用返回值完成后,可以使用调用者(free()
)中返回的指针调用main()
。