realloc()之后的分段错误。无法将指定的内存分配给指针

时间:2012-04-25 07:00:51

标签: c pointers segmentation-fault realloc

我正在尝试使用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;
        // ...
    }
}

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

3 个答案:

答案 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)

乍一看,我没有看到可能导致崩溃的问题 - 基于某些的寻址有点奇怪,但并非不正确。代码中可能存在一个问题,即您没有显示导致堆或堆栈损坏导致重新分配调用变得更糟。或者,如果您正在使用优化进行编译,那么您的调试器可能会对实际发生崩溃的位置感到困惑。您还会混淆MyDataMyContent,但我认为这只是因为您在编写代码时出错了。

另请注意,如果realloc失败,您将在之后的行崩溃,因为您将写入空指针。你需要在tempPtr is NULL中止,而不是释放旧指针。但是,这会导致与您指示的行不同的错误。

我建议你在valgrind下运行你的程序来查看它报告错误的位置 - 第一个这样的错误可能是罪魁祸首。