不可能导致c链表

时间:2014-01-11 08:52:39

标签: c macos linked-list stack-overflow

我一直在尝试创建一个简单的c链表,但我的结果非常有趣

这是我的代码:

#include "stdio.h"
#include "string.h"
#include "stdlib.h"

typedef char * String;

typedef struct node{
    String value;
    struct node * next;
    struct node * prev;
}Node;

struct node * createLinkList(){
    struct node * root=malloc(sizeof(Node));
    root->value="head";
    root->prev=NULL;
    root->next=NULL;
    return root;
}

Node * insert(String val,Node * root){
    Node * tempNode=root;
    Node * newNode=malloc(sizeof(Node));
    printf("head value : %s\n",tempNode->value );
    while(tempNode->next !=  NULL){
        tempNode=tempNode->next;
        printf("latest node value : %s\n", tempNode->value);
    }
    newNode->prev=tempNode;
    newNode->next=NULL;
    newNode->value=val;
    printf("newly added node value : %s\n", newNode->value);
    tempNode->next=newNode;
    return root;
}

int main (int argc, char const *argv[])
{
    Node * dblList=createLinkList();
    String val=malloc(sizeof(char)*100);
    for (int i = 0; i < 2; ++i)
    {
        printf("please enter value(node #%i): ",i);
        scanf("%s",val);
        dblList=insert(val,dblList);
    }
}

这是我得到的结果:

please enter value(node #0): one
head value : head
newly added node value : one
please enter value(node #1): two
head value : head
latest node value : two
newly added node value : two

任何人都可以解释这里发生了什么???? 我的意思是当我输入第二个值时 最新节点值必须是我输入的第一个值,但它是新输入的值!

它是堆栈溢出还是我做错了什么!?

1 个答案:

答案 0 :(得分:2)

你应该在循环中分配一个新字符串,而不是之前:

#define LEN 100
for (int i = 0; i < 2; ++i)
{
    char* val=malloc(LEN);
    memset (val, 0, LEN);
    printf("please enter value(node #%i): ",i);
    fflush(NULL);
    fgets(val, LEN, stdin);
    dblList=insert(val,dblList);
}

实际上你应该更好地使用getline(3)和代码

for (int i = 0; i < 2; ++i)    {
    char* line=NULL;
    size_t linsiz=0;
    printf("please enter value(node #%i): ",i);
    fflush(NULL);
    ssize_t linlen = getline(&line,&linsiz,stdin);
    dblList=insert(line,dblList);
}

不要忘记稍后free在堆内分配的内存区域!阅读memory management&amp; C dynamic memory allocation&amp; memory leak wikipages。还要考虑valgrind ...

编译所有警告和调试信息(gcc -Wall -g)并使用调试器(gdb)。或者至少,调试打印存储区的地址,例如,在几个地方放一行像

    printf("at %s:%d val=%p\n", __FILE__, __LINE__, (void*)val);