【问题标题】:C89 Deleting Linked ListsC89 删除链表
【发布时间】:2016-07-27 02:18:42
【问题描述】:

我正在尝试编写一个从 Excel 文件导入数据并将名称存储在链接列表中的程序。第一列包含命令 {add, remove, flush},如果命令为 add,则第二列包含名称。

它将名称添加到列表的末尾,从前面删除名称,当它刷新时,它会从内存中删除整个列表。添加检测名称是否已包含(尚未写入)刷新和删除还检测队列是否为空。

示例文件:

add      dave

add      mike

remove 

add      paul

flush

add      steve

示例输出:

add:     dave

add:     dave, mike

remove:  mike

 flushing queue

add:      steve

我的问题是我的刷新命令没有正确删除列表。代码必须符合 c89。感谢您提供的任何帮助。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct node {
struct node* next;
char name[50];
};

struct node* addNode(char *word);
void freeNodes(struct node* head);
void removeNode (struct node* head);

int main(void)
{
struct node* head = NULL, *tail, *temp;
char buffer[50];
int i;
char *word = " ";
char *del = " ,\n";
FILE *fp;

fp = fopen("queue-data.csv", "r");

while( fgets(buffer, sizeof(buffer), fp) != NULL )
{
    word = strtok(buffer, del);

    /********     ADD      *********/

    if( strcmp(word,"add") == 0)
    {
        word = strtok(NULL, del);
        temp = addNode(word);
        if(head == NULL)
            head = temp;
        else
            tail->next = temp;

        tail = temp;
        temp = head;

        printf("   add:");
        printf(" %s", temp->name);
        temp = temp->next;

        while(temp != NULL) 
        {
            printf(", %s", temp->name);
            temp = temp->next;
        }
        printf("\n");
    }

    /********     REMOVE      *********/

    else if( strcmp(word,"remove") == 0)
    {
        printf("remove:");
        if (head == NULL)
            printf(" queue is empty");
        else
        {
            removeNode(head);
        }
        printf("\n");
    }


    /********     FLUSH      *********/


    else if( strcmp(word,"flush") == 0)
    {
        if (head == NULL)
            printf(" flush: queue is empty");
        else
            freeNodes( head );
        printf("\n");
    }

}
freeNodes( head );
}


struct node* addNode(char *word)
{
struct node* temp = malloc( sizeof(struct node) );
strcpy(temp->name, word);
temp->next = NULL;

return temp;
}

void freeNodes(struct node* head)
{
struct node* temp;

printf(" flushing queue");
while(head != NULL)
{
    temp = head->next;
    free(head);
    head = temp;
}
}

void removeNode (struct node* head)
{
struct node* temp;

temp = head->next;
free(head);
head = temp;
printf(" %s", temp->name);
temp = temp->next;
while(temp != NULL) 
{
    printf(", %s", temp->name);
    temp = temp->next;
}
}

【问题讨论】:

  • 只是评论:C 是性能最好的语言,而链表是性能最差的数据结构,因为缓存局部性。为什么要使用一种难以使用的语言,然后故意破坏其主要用例?如果您不关心性能,请使用 Excel 的 VBA。
  • 您能否定义“未正确删除列表”?程序是直接退出而不删除任何内容,还是删除了其中的一些内容,或者只是崩溃了?

标签: linked-list c89


【解决方案1】:

问题在于您的 removeNode() 函数。
它改变了指针头的地址——本地在removeNode()中的地址,并释放了它之前指针的节点内存,而主函数中的指针头没有改变。所以当你调用removeNode(head) 时,main 中的指针头仍然指向在removeNode() 函数中被释放的内存,所以之后它出错了。
这些是一些解决方案:

  • 将指针头定义为全局变量
  • 函数 removeNode() 应在更改后返回头指针。像这样:
    struct node* removeNode(struct node* head){}

如果有帮助,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-06
    • 2013-11-22
    • 2017-05-19
    • 2018-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多