列表分配的列表变成垃圾

时间:2012-09-06 16:18:48

标签: c list pointers parameters

我遇到以下问题:

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-&gt; nextPtr会导致段错误。对于循环的每次迭代。 hw仍然很好,但它的指针值永远不会正确更新。

即使我试图将结构的内存分配移动到函数中,我也遇到了相同(或类似)的问题。

有人能指出我正确的方向吗?

2 个答案:

答案 0 :(得分:0)

您的BuildList函数存在的问题是您正在将指针传递给struct hwpoints,并且您正在尝试重新分配参数所指向的内容。由于C中的函数参数是按值传递,因此您只更改函数接收的指针的副本,并且这些更改不会反映在呼叫者。

可以使用这个指针来修改列表的内容:你可以改变例如hw->coursehw->nextPtr,您可以在列表中移动元素。但是您无法更改头部hw指向,因此您无法在列表的开头插入元素。

如果你想改变你的头指针,就像在这些陈述中一样:

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

然后你需要传递一个指向指针的指针:

void BuildList(cs460hwp *hw)

并在函数体中根据需要取消引用它。

我无法确定这是您正在观察的输出的原因,这可能是由于其他问题所致。但是,如果在对BuildList进行一些调用之后,从头指针开始等于NULL,那么您尝试打印列表,假设它具有有效节点,您可以看到垃圾数据。 / p>

感谢@ Mike的回答,我们也看到你没有为列表节点分配足够的空间:

stuInsert = malloc(sizeof(cs460hwp));

只会为指针分配足够的空间,因为cs460hwp typedef是指向struct hwpoints的指针。您需要为结构分配足够的空间,而不是指向它的指针:

stuInsert = malloc(sizeof(struct hwpoints));

答案 1 :(得分:0)

两个问题。

1)正如pb2q所提到的,您正在传递指向结构的指针并尝试分配arg指向的内容。这是编译器允许的,但它不能在函数外为你做任何事情。在以下情况下可能没问题:

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

是你的全部功能。我不知道作业,所以你需要弄清楚你是否可以接受。

2)更大的问题:

stuInsert = malloc(sizeof(cs460hwp)); 

你有没有检查出尺寸(cs460hwp)是多少? 4.你为指针的大小分配了足够的内存,而不是你的结构大小。我很确定这不是你想要做的,这就是杀了你的原因。只是为了踢,用malloc(100)替换它,看看你的问题是否消失。如果是这样,你只需要弄清楚你真正想要的尺寸。 ;)