0

変更できない次のコードがあります

typedef struct 
{
    char* firstName;
    char* lastName;
    int id;
    float mark;
}* pStudentRecord;

現在、次の方法でメモリを割り当てています。

g_ppRecords = (pStudentRecord*) malloc (sizeof(pStudentRecord*) *(g_numRecords));       /*allocate required memory for the array of pointers to instances of pStudentRecord*/

/*populate the data structure with records from the text file*/
while (count<g_numRecords)
{   
    fscanf(g_pf,"%s %s %i %f\n",&fn,&ln,&i,&m);

    /*allocate memory for each student record. the pointer to each of these will be stored in the array g_ppRecords*/
    g_ppRecords[count]=(pStudentRecord)malloc(sizeof(char*)*2+sizeof(int)+sizeof(float));

    /*allocate memory for the firstName and lastName on the heap for each record. use only as much space as is required*/
    g_ppRecords[count]->firstName=(char*)malloc(strlen(fn));
    g_ppRecords[count]->lastName=(char*)malloc(strlen(ln));

    /*assign values stored in local variables to the ones on heap for each record*/
    strcpy(g_ppRecords[count]->firstName,fn);
    strcpy(g_ppRecords[count]->lastName,ln);
    g_ppRecords[count]->id=i;
    g_ppRecords[count]->mark=m;

    ++count; /*onto next record*/
}

しかし、私はそれを解放するのに苦労しています。これは私がやっていることです:

while (count<g_numRecords)
{
        /*copy variables in the struct instance into local variables*/
    strcpy(fn,g_ppRecords[count]->firstName);
    strcpy(ln,g_ppRecords[count]->lastName);
    id=g_ppRecords[count]->id;
    mark=g_ppRecords[count]->mark;

    free(g_ppRecords[count]->firstName);
    g_ppRecords[count]->firstName=NULL;
    free(g_ppRecords[count]->lastName);
    g_ppRecords[count]->lastName=NULL;
    free(g_ppRecords[count]);

    ++count;

    #ifdef DEBUG
        printf("\n%s %s %d %.2f",fn,ln,id,mark);
    #endif

    /*detect any errors while writing to file*/
    if(fprintf(g_pf,"%s %s %d %.2f\n",fn,ln,id,mark) ==-1)
        perror("");
    else{
        #ifdef DEBUG
            printf("success");
        #endif
    }

    #ifdef DEBUG
        printf("return val=%d",now);
    #endif
}

    free(g_ppRecords);  /*free memory after writing to file is complete*/
    g_ppRecords=NULL;   /*make pointer point to NULL*/
    fclose(g_pf);       /*close file stream*/
}

次のようにメモリの割り当てに関連している可能性があることはわかっています。

g_ppRecords[count]=(pStudentRecord)malloc(sizeof(char*)*2+sizeof(int)+sizeof(float));

しかし、私はそれを次のように割り当てることができません

g_ppRecords[count]=(pStudentRecord)malloc(sizeof(pStudentRecord));

助けてください!

4

2 に答える 2

1

コードは次のようになります。

typedef struct 
{
    char* firstName;
    char* lastName;
    int id;
    float mark;
} StudentRecord;

/* Allocate memory for each student record. */
g_ppRecords[count] = (StudentRecord*)malloc(sizeof(StudentRecord));

/* Allocate memory for the firstName and lastName on the heap. */
g_ppRecords[count]->firstName = (char*)malloc(strlen(fn)+1);
g_ppRecords[count]->lastName = (char*)malloc(strlen(ln)+1);

文字列のトレーニング ゼロにスペースを割り当てていないため、メモリが破損します。sizeof(struct)レコード自体にスペースを割り当てる場合に使用することをお勧めします。この構造体には、フィールド間またはレコード全体の後に、サイズの計算に含まれない可能性のあるパディングが含まれている場合があります。

ヘッダーを変更できない場合は、次のように記述します。

pStudentRecord DummyPtrVar;
g_ppRecords = (pStudentRecord*)malloc(sizeof(*DummyPtrVar)*g_numRecords);   

sizeofpStudentRecord*の下の記述は正しくありません。これにより、レコード自体にアクセスする代わりに、ダブルポインターが作成されます。C/C++ では、指定された型への単純なアクセスは許可されていません。しかし、変数を定義すると、疑似逆参照を行うことができます。これはきちんとしたものではありませんが、99% のコンパイラで動作すると確信しています。

于 2012-09-29T04:41:25.087 に答える
0

あなたのコードの主な問題は、g_ppRecords の割り当てだと思います。

"g_ppRecords = (pStudentRecord*) malloc (sizeof(pStudentRecord*) *(g_numRecords));"

に変更する必要があります

"g_ppRecords = (pStudentRecord*) malloc (sizeof(pStudentRecord) *(g_numRecords));"

もちろん、@Kirill が言うように、char 配列には '\n' を含めるためのバイトを残す必要があります。

于 2012-09-29T12:43:40.857 に答える