0

我正在尝试使用 realloc() 分配一些内存。到目前为止,这有效。但是,如果我想将分配的内存分配给结构变量中的指针,则会出现分段错误:

// 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;
        // ...
    }
}

我无法弄清楚这里出了什么问题。有什么建议么?谢谢你的帮助。

4

3 回答 3

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);
}
于 2012-04-25T07:28:41.603 回答
0

乍一看,我没有看到可能导致崩溃的问题——基于个数的寻址有点奇怪,但并非不正确。代码中可能存在您未显示的问题,导致堆或堆栈损坏,而 realloc 调用会使情况变得更糟。或者,如果您正在使用优化进行编译,您的调试器可能会对崩溃实际发生的位置感到困惑。你也很困惑MyDataand MyContent,但我认为这只是因为你在编辑代码时出错了。

另请注意,如果realloc失败,您将在您指示的那一行之后崩溃,因为您将写入一个空指针。您需要中止 if tempPtr is NULL,而不仅仅是释放旧指针。但是,这再次导致与您指示的线路不同的故障。

我建议在 valgrind 下运行您的程序以查看它报告错误的位置 - 发生的第一个此类错误可能是罪魁祸首。

于 2012-04-25T07:12:29.633 回答
0

检查新分配的内存时,您的条件是错误的。它应该是:

if (tempPtr == NULL) {
  // handle error condition or continue with original 'dataPtr->values'
}
else {
  dataPtr->values = tempPtr;
}

请记住,realloc()这不一定将一个块转移到另一个块。有时它可能会在同一个指针区域中分配内存。

于 2012-04-25T07:08:40.800 回答