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

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

谁能指出我正确的方向?

4

2 回答 2

0

您的函数的一个问题BuildList是您正在传递一个指向 a 的指针struct hwpoints,并且您正在尝试重新分配参数指向的内容。由于 C 中的函数参数是按值传递的,因此您只需更改函数接收到的指针的副本,而这些更改不会反映在调用者中。

可以使用此指针来修改列表的内容:您可以更改例如hw->coursehw->nextPtr,您可以在列表中移动元素。但是你不能改变头hw指向东西,所以你不能在列表的开头插入元素。

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

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

然后您需要将指针传递给指针:

void BuildList(cs460hwp *hw)

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

我不能确定这是您观察到的输出的原因,这可能是由于其他问题。但是,如果在调用了一定次数后BuildList,从头指针等于 开始NULL,您试图打印您的列表,假设它具有有效节点,您可能会看到垃圾数据。

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

stuInsert = malloc(sizeof(cs460hwp));

只会为指针分配足够的空间,因为cs460hwpis typedef'd 是一个指向struct hwpoints. 您需要为结构分配足够的空间,而不是指向它的指针:

stuInsert = malloc(sizeof(struct hwpoints));
于 2012-09-06T16:27:46.027 回答
0

两个问题。

1)正如 pb2q 提到的,您正在传递一个指向结构的指针并尝试分配 arg 指向的内容。编译器允许这样做,但在函数之外它不会为您做任何事情。在您的情况下,如果:

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

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

2)更大的问题:

stuInsert = malloc(sizeof(cs460hwp)); 

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

于 2012-09-06T16:51:07.317 回答