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

新しく割り当てられたメモリをチェックするための条件が間違っています。そのはず:

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

realloc()必ずしも1つのブロックを別のブロックに転送するとは限らないことに注意してください。同じポインタ領域にメモリを割り当てる場合があります。

于 2012-04-25T07:08:40.800 に答える
0

一見すると、そこでクラッシュを引き起こす可能性のある問題は見当たりません。つまり、アドレスベースのアドレス指定は少し奇妙ですが、正しくありません。表示していないコードに問題があり、ヒープまたはスタックが破損し、realloc呼び出しが悪化する可能性があります。または、最適化を使用してコンパイルしている場合、クラッシュが実際に発生している場所についてデバッガーが混乱する可能性があります。あなたも混乱MyDataしてMyContentいますが、それはコードの編集中にエラーが発生したからだと思います。

また、失敗した場合は、nullポインターに書き込むため、指定した行のreallocの行でクラッシュすることにも注意してください。古いポインタを解放するだけでなく、の場合は中止する必要があります。繰り返しになりますが、これにより、指定したものとは異なる回線で障害が発生します。tempPtr is NULL

プログラムをvalgrindで実行して、エラーが報告される場所を確認することをお勧めします。このようなエラーが最初に発生したのは、原因である可能性があります。

于 2012-04-25T07:12:29.633 に答える