为什么我的双向链表的元素没有正确显示?

时间:2013-03-17 13:08:41

标签: c pointers void-pointers doubly-linked-list

以下程序接收ins "name_to_insert" birthdate形式的输入字符串,并应将此信息插入双向链接列表中。每次插入后都会显示列表的内容以及元素数量。正确显示元素数量,但不是名称和出生日期,而是显示 2686707 n次(n =列表中的元素数)。

我怀疑我的打印功能 printList()有问题,但我无法弄清楚是什么。

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

typedef struct dataStructure
{
    int birthday;
    char *name;
} dataStructure;

int main()
{
    ListT *l=createList();
    char op[4], nameTemp[30], *name, s[50];
    int date;
    while (scanf("%[^\n]%*c", s)==1)
    {
        sscanf(s, "%s", op);
        if (strcmp(op, "ins")==0)
        {
            sscanf(s, "%*s %[^0-9]%d", nameTemp, &date);
            name=nameTemp+1; // Remove opening quotation mark
            name[strlen(name)-2]='\0'; // Remove closing quotation mark
                NodeT *p=createNode();
                p->data=(dataStructure*)malloc(sizeof(dataStructure));
                ((dataStructure*)p->data)->birthday=date;
                ((dataStructure*)p->data)->name=name;
                insertLastNode(l, p);
                printf("List length: %d\n", l->length);
                printList(l);
        }
    }
    return 0;
}

void printList(ListT *l)
{
    NodeT *p=l->first;
    while (p)
    {
        printf("%d %s\n", (((dataStructure*)p->data)->birthday, (dataStructure*)p->data)->name);
        p=p->next;
    }
    printf("--\n");
}

DLList.h的内容

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

typedef struct nodetype
{
    struct nodetype *prev, *next;
    void *data;
} NodeT;

typedef struct
{
    int length;
    NodeT *first, *last;
} ListT;

NodeT *createNode();
ListT *createList();
void insertLastNode(ListT *l, NodeT *p);

DLList.c 的内容:

#include "DLList.h"

NodeT *createNode()
{
    NodeT *p=(NodeT*)malloc(sizeof(NodeT));
    p->next=p->prev=NULL;
    return p;
}

ListT *createList()
{
    ListT *l=(ListT*)malloc(sizeof(ListT));
    l->first=l->last=NULL;
    l->length=0;
    return l;
}

void insertLastNode(ListT *l, NodeT *p)
{
    if (l->first==NULL)
    {
        l->first=l->last=p;
        p->prev=p->next=NULL;
        l->length++;
    }
    else
    {
        p->prev=l->last;
        p->next=NULL;
        l->last->next=p;
        l->last=p;
        l->length++;
    }
}

3 个答案:

答案 0 :(得分:1)

在您的程序中,您将指针指向name,如下所示:

((dataStructure*)p->data)->name=name;

此名称源自sscanf,如下所示:

sscanf(s, "%*s %[^0-9]%d", nameTemp, &date);
name=nameTemp+1; // Remove opening quotation mark
name[strlen(name)-2]='\0'; // Remove closing quotation mark

这意味着对于循环的每次运行,您将读入相同的nameTempname数组并将其存储到链接列表中。对于循环的每次运行,您可能必须分配一个单独的空间来存储name并将其分配给您的节点。

编辑1:

创建新节点时,还存在一个类型转换问题。 p->data属于void *类型,我相信在代码中,新分配的内存类型为dataStructure *,如下所示

p->data=(dataStructure*)malloc(sizeof(dataStructure));

您还可以更改数据结构定义,如下所示

typedef struct dataStructure
{
    int birthday;
    char name[64]; // Change from pointer to an array
} dataStructure;

并修改循环中的逻辑以复制名称,如下所示:

p->data=(dataStructure*)malloc(sizeof(dataStructure));
((dataStructure*)p->data)->birthday=date;
strcpy(((dataStructure*)p->data)->name, name); // Modified from pointer assignment to strcpy

答案 1 :(得分:1)

代码中有两个错误。

<强>首先: 而不是

((dataStructure*)p->data)->name=name;

DO

((dataStructure*)p->data)->name = (char*)malloc(strlen(name)+1);
strcpy(((dataStructure*)p->data)->name, name);

避免内存泄漏。

<强>第二 在printList函数中,括号出现错误。请按以下步骤操作:

printf("%d %s\n", ((dataStructure*)p->data)->birthday, ((dataStructure*)p->data)->name);

其他一切都有效。这是测试程序时得到的输出。 enter image description here

答案 2 :(得分:0)

在调试器中运行此命令以确切了解您的函数正在执行的操作。例如,如果您从Unix命令行运行,请使用-g标志进行编译,然后在gdb中运行。在功能开头设置断点,这会给您带来麻烦。谷歌有点像“gdb备忘单”的细节,很容易。