我正在尝试使用realloc()分配一些内存。这项工作到目前为止。但是如果我想将分配的内存分配给struct变量中的指针,我会遇到分段错误:
// in header
typedef struct {
int a;
char test[20];
} MyContent;
typedef struct {
MyContent* values;
// simmilar to: MyContent values[]
// ... some other stuff
} MyData;
// in source
void myFunction(MyData* dataPtr) {
dataPtr->values = NULL;
MyData* tempPtr = NULL;
for (int i = 1; i < 10; i++) {
tempPtr = (MyContent*) realloc(dataPtr->values, i * sizeof(MyContent));
if (tempPtr == NULL) {
free(dataPtr->values);
break;
}
dataPtr->values = tempPtr; // Here I get the segmentation fault
dataPtr->values[(i-1)].a = 42;
// ...
}
}
我无法弄清楚这里出了什么问题。有什么建议?谢谢你的帮助。
答案 0 :(得分:1)
好像你编辑了代码。编辑过的代码工作正常。
#include<stdio.h>
#include<malloc.h>
#include<string.h>
// in header
typedef struct {
int a;
char test[20];
} MyContent;
typedef struct {
MyContent* values;
// simmilar to: MyContent values[]
// ... some other stuff
} MyData;
// in source
void myFunction(MyData* dataPtr) {
dataPtr->values = NULL;
MyData* tempPtr;
for (int i = 1; i < 10; i++) {
tempPtr = (MyData*) realloc(dataPtr->values, i * sizeof(MyContent));
if (tempPtr == NULL) {
if(dataPtr->values)
free(dataPtr->values);
printf("realloc() failed\n");
return ;
}
dataPtr->values = (MyContent*)tempPtr; // Here I get the segmentation fault
dataPtr->values[(i-1)].a = 42+i;
strcpy(dataPtr->values[(i-1)].test,"name");
}
}
void PrintData(MyData* dataPtr) {
for (int i = 1; i < 10; i++)
printf("We have %s at %d\n",dataPtr->values[(i-1)].test,dataPtr->values[(i-1)].a);
}
main() {
MyData Sample;
myFunction(&Sample);
PrintData(&Sample);
}
答案 1 :(得分:0)
检查新分配的内存是错误的。它应该是:
if (tempPtr == NULL) {
// handle error condition or continue with original 'dataPtr->values'
}
else {
dataPtr->values = tempPtr;
}
请记住,realloc()
不一定将一个块传输到另一个块。有时它可能会在同一指针区域中分配内存。
答案 2 :(得分:0)
乍一看,我没有看到可能导致崩溃的问题 - 基于某些的寻址有点奇怪,但并非不正确。代码中可能存在一个问题,即您没有显示导致堆或堆栈损坏导致重新分配调用变得更糟。或者,如果您正在使用优化进行编译,那么您的调试器可能会对实际发生崩溃的位置感到困惑。您还会混淆MyData
和MyContent
,但我认为这只是因为您在编写代码时出错了。
另请注意,如果realloc
失败,您将在之后的行崩溃,因为您将写入空指针。你需要在tempPtr is NULL
中止,而不是释放旧指针。但是,这会导致与您指示的行不同的错误。
我建议你在valgrind下运行你的程序来查看它报告错误的位置 - 第一个这样的错误可能是罪魁祸首。