1

以下の点で困っています。

void BuildList(cs460hwp hw)
{

    FILE* fp;
    fp = fopen("HW2input.dat", "r");
    if(fp == NULL)
    {
        printf("Couldn't open the file.");
        return;
    }
    int numStudents;
    int i;
    bool success;
    char* dueDate = malloc(9*sizeof(char));
    char* course = malloc(7*sizeof(char));
    char* wsuid = malloc(9*sizeof(char));
    char* subDate = malloc(9*sizeof(char));
    double points1 = 0;
    double points2 = 0;
    cs460hwp stuInsert = NULL;
    fscanf(fp, "%d", &numStudents);
    fscanf(fp, "%s", dueDate);
    for(i = 0; i < numStudents; i++)
    {
        stuInsert = malloc(sizeof(cs460hwp));
        fscanf(fp, "%s %s %s %lf", course, wsuid, subDate, &points1);
        strcpy(stuInsert->course, course);
        strcpy(stuInsert->wsuid, wsuid);
        strcpy(stuInsert->subdate, subDate);
        stuInsert->points1 = points1;
        stuInsert->points2 = CalculatePoints(dueDate, subDate, points1);
        stuInsert->nextPtr = NULL;
        if(hw == NULL)
        {
            hw = stuInsert;
        } 
        else
        {
            stuInsert->nextPtr = hw;
            hw = stuInsert;
        }
    }
    free(course);
    free(wsuid);
    free(subDate);
    free(dueDate);
    PrintGrades(hw);
    fclose(fp);
}

struct hwpoints
{
    char course[7];
    char wsuid[9];
    char subdate[9];
    double points1;
    double points2;
    struct hwpoints *nextPtr;
};

typedef struct hwpoints *cs460hwp;

ここでの私の目標は、すべてのエントリをリストの一番上に挿入することです。ただし、nextPtr (else 句など) に何かを割り当てようとすると、ガベージ値でいっぱいになります。それらはほとんど古いデータの切り捨てられたバージョンであり、ヒープから取得されていると私は信じています。私は(たくさん)読んできましたが、この特定の問題に関するアドバイスを見つけるのに苦労しています。

nextPtr は常にジャンクになり、nextPtr->nextPtr は segfault を引き起こします。ループの反復ごとに。hw は問題ありませんが、そのポインター値は適切に更新されません。

構造体のメモリ割り当てを関数に移動しようとしても、同じ (または同様の) 問題が発生しました。

誰かが私を正しい方向に向けることができますか?

4

2 に答える 2

0

2 つの問題。

1) pb2q が述べたように、ポインターを構造体に渡し、引数が指すものを割り当てようとしています。これはコンパイラによって許可されていますが、関数の外では何もしません。次の場合は問題ありません。

void main()
{
   cs460hwp hw = NULL;
   BuildList(hw);
   return;
}

あなたの機能の全体です。私は割り当てを知らないので、それがあなたに受け入れられるかどうかを判断する必要があります.

2) より大きな問題:

stuInsert = malloc(sizeof(cs460hwp)); 

sizeof(cs460hwp) がどのようになるかを確認しましたか? それは 4 です。構造体のサイズではなく、ポインターのサイズに十分なメモリを割り当てています。これはあなたがやりたいことではなく、これがあなたを殺していることだと確信しています。とりあえず、malloc(100) に置き換えて、問題が解決するかどうかを確認してください。その場合は、実際に必要なサイズを把握する必要があります。;)

于 2012-09-06T16:51:07.317 に答える
0

関数の問題BuildListは、ポインタを に渡しstruct hwpoints、引数が指すものを再割り当てしようとしていることです。C の関数引数は値渡しであるため、関数が受け取るポインターのコピーを変更するだけであり、それらの変更は呼び出し元には反映されません。

このポインター使用して、リストの内容を変更できます。たとえばhw->course、 またはを変更したりhw->nextPtr、リスト内の要素を移動したりできます。ただし、 head が指すものを変更することはできないため、リストの先頭に要素を挿入することはできません。hw

次のステートメントのように、ヘッド ポインターを変更する場合は、次のようにします。

hw = stuInsert;
// ...
hw = stuInsert;

次に、ポインターにポインターを渡す必要があります。

void BuildList(cs460hwp *hw)

そして、関数の本体で必要に応じて参照解除します。

これがあなたが観察している出力の原因であるとは確信できません。これは他の問題が原因である可能性があります。BuildListしかし、 に等しいヘッド ポインタで始まる を何度か呼び出した後NULL、リストに有効なノードがあると仮定してリストを印刷しようとすると、ガベージ データが表示される可能性があります。

@Mike の回答のおかげで、リスト ノードに十分なスペースを割り当てていないこともわかります。

stuInsert = malloc(sizeof(cs460hwp));

はへのポインターになるため、ポインターに十分なスペースのみを割り当てます。構造体へのポインターではなく、構造体に十分なスペースを割り当てる必要があります。cs460hwptypedefstruct hwpoints

stuInsert = malloc(sizeof(struct hwpoints));
于 2012-09-06T16:27:46.027 に答える