列出分配的列表变成垃圾

时间:2021-07-07 23:25:21

I'm having some trouble with the following:

我遇到以下问题:

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;

My goal here is to insert every entry to the top of the list. However, whenever I try to assign anything to nextPtr (such as in the else clause), it gets filled with garbage values. They're mostly truncated versions of old data, which leads me to believe they're being taken from the heap. I've been reading (a lot), but I'm having trouble finding advice on this particular problem.

我的目标是将每个条目插入列表顶部。但是,每当我尝试将任何内容分配给nextPtr时(例如在else子句中),它就会被垃圾值填充。它们大多是旧数据的截断版本,这让我相信它们是从堆中取出的。我一直在阅读(很多),但我很难就这一特定问题寻求建议。

nextPtr always becomes junk, and nextPtr->nextPtr causes a segfault. For every iteration of the loop. hw remains fine, but its pointer value never gets updated properly.

nextPtr总是变成垃圾,而nextPtr-> nextPtr会导致段错误。对于循环的每次迭代。 hw仍然很好,但其指针值永远不会正确更新。

Even when I've attempted to move the memory allocation for the struct into a function, I've had the same (or similar) issues.

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

Can anyone point me in the right direction?

谁能指出我正确的方向?

2 个解决方案

#1


0  

Two problems.

1) As pb2q mentioned, you are passing a pointer to a struct and trying to assign what the arg points to. That's allowed by the compiler, but it doesn't do anything for you outside the function. It might be OK in your case if:

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

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

Is the whole of your function. I don't know the assignment so you need to figure out if that's acceptable to you or not.

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

2) The much bigger problem:

2)更大的问题:

stuInsert = malloc(sizeof(cs460hwp)); 

Did you check what sizeof(cs460hwp) comes out to be? it's 4. You're allocating enough memory for the size of a pointer, not the size of your structure. I'm pretty sure this is not what you want to do and this is what is killing you. Just for kicks, replace it with malloc(100) and see if your problem goes away. If so you just need to figure out what size you really want. ;)

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

#2


0  

A problem with your BuildList function is that you're passing a pointer to a struct hwpoints, and you're trying to re-assign what the argument points to. Since function arguments in C are pass-by-value you're only changing the copy of the pointer that your function receives, and those changes won't be reflected in the caller.

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

You can use this pointer to modify the contents of the list: you can change e.g. hw->course or hw->nextPtr, you can move elements around in your list. But you can't change what the head, hw points to, so you can't insert elements at the beginning of the list.

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

If you want to change your head pointer, as in these statements:

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

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

Then you'll need to pass a pointer to the pointer:

然后你需要传递指针指针:

void BuildList(cs460hwp *hw)

And de-reference it as necessary in the body of the function.

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

I can't be sure that this is the cause of the output that you're observing, which may be due to other problems. But if, after some number of calls to BuildList, beginning with a head pointer equal to NULL, you're trying to print your list assuming that it has valid nodes, you could see garbage data.

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

Thanks to @Mike's answer, we see also that you're not allocating enough space for your list nodes:

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

stuInsert = malloc(sizeof(cs460hwp));

Will only allocate enough space for a pointer, since cs460hwp is typedef'd to be a pointer to struct hwpoints. You need to allocate enough space for the structure, not a pointer to it:

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

stuInsert = malloc(sizeof(struct hwpoints));

#1


0  

Two problems.

1) As pb2q mentioned, you are passing a pointer to a struct and trying to assign what the arg points to. That's allowed by the compiler, but it doesn't do anything for you outside the function. It might be OK in your case if:

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

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

Is the whole of your function. I don't know the assignment so you need to figure out if that's acceptable to you or not.

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

2) The much bigger problem:

2)更大的问题:

stuInsert = malloc(sizeof(cs460hwp)); 

Did you check what sizeof(cs460hwp) comes out to be? it's 4. You're allocating enough memory for the size of a pointer, not the size of your structure. I'm pretty sure this is not what you want to do and this is what is killing you. Just for kicks, replace it with malloc(100) and see if your problem goes away. If so you just need to figure out what size you really want. ;)

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

#2


0  

A problem with your BuildList function is that you're passing a pointer to a struct hwpoints, and you're trying to re-assign what the argument points to. Since function arguments in C are pass-by-value you're only changing the copy of the pointer that your function receives, and those changes won't be reflected in the caller.

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

You can use this pointer to modify the contents of the list: you can change e.g. hw->course or hw->nextPtr, you can move elements around in your list. But you can't change what the head, hw points to, so you can't insert elements at the beginning of the list.

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

If you want to change your head pointer, as in these statements:

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

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

Then you'll need to pass a pointer to the pointer:

然后你需要传递指针指针:

void BuildList(cs460hwp *hw)

And de-reference it as necessary in the body of the function.

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

I can't be sure that this is the cause of the output that you're observing, which may be due to other problems. But if, after some number of calls to BuildList, beginning with a head pointer equal to NULL, you're trying to print your list assuming that it has valid nodes, you could see garbage data.

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

Thanks to @Mike's answer, we see also that you're not allocating enough space for your list nodes:

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

stuInsert = malloc(sizeof(cs460hwp));

Will only allocate enough space for a pointer, since cs460hwp is typedef'd to be a pointer to struct hwpoints. You need to allocate enough space for the structure, not a pointer to it:

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

stuInsert = malloc(sizeof(struct hwpoints));