链接列表数据全部相同

时间:2013-04-06 05:03:08

标签: c linked-list

我正在尝试从.txt文件中读取输入,并将其添加到单个链接列表中。我遇到的问题是正在创建并正确连接节点(我得到了正确的长度),但在添加所有节点后,每个数据字段都是相同的。我想知道问题是什么,以及如何解决它。已经有一段时间了!

添加功能:

#include "linkedList.h"
#include <stdlib.h>
#include <string.h>

void addOrdered(Node ** Head,char * input)
{

        printf("\nInput: %s\n",input);

        Node * cur = (*Head);

        Node * newNode = malloc(sizeof(Node));
        newNode->Data = malloc(sizeof(Person));

        newNode->Data->FName = strtok(input," ");
        newNode->Data->LName = "test";
        newNode->Data->id = 5;
        newNode->Next = NULL;

        if(cur == NULL)
        {
            (*Head) = newNode;
        }
        else
        {

            for(;cur->Next != NULL;cur = cur->Next)
            {
                printf(" Cur->Next ");
            }

            cur->Next = newNode;
        }
}

处理文件:

void processFile(Node ** Head, FILE * fd)
{
    char * input = malloc(sizeof(char)*SIZE);

    while(fgets(input,SIZE,fd) != NULL)
    {
        addOrdered(Head,input);
    }


    free(input);
}

2 个答案:

答案 0 :(得分:1)

strtok返回指向string中找到的最后一个标记的指针。 如果没有要检索的标记,则返回空指针。 您需要执行pch = strtok(input," ");

之类的操作

答案 1 :(得分:1)

代码中的错误是:一旦在processFile()函数中调用newNode->Data->FName并且在运行时访问空闲内存导致“未定义的行为”,则分配给free(input)的地址将变为无效。

更正您的代码:

而不是简单的分配,如:

newNode->Data->FName = strtok(input," ");

在单独的内存中分配和复制,如下所示:

char *ptr =  strtok(input," ");
newNode->Data->FName = malloc(strlen(ptr)+1);
strcpy(newNode->Data->FName, ptr);

实际上,您是在addOrdered()中从input地址空间分配内存地址,并在free()函数中生成processFile()

我在下面详细解释您的代码:

首先阅读:char * strtok ( char * str, const char * delimiters );手册:

  

在第一次调用时,函数需要一个C字符串作为str的参数,其第一个字符用作扫描标记的起始位置。在后续调用中,函数需要一个空指针,并在最后一个令牌结束后立即使用该位置作为扫描的新起始位置。

     

返回值

     

指向字符串中找到的最后一个标记的指针。   如果没有要检索的标记,则返回空指针。

不会发送新的内存,而是来自input的内存,你最近免费()。要理解strtok()函数的工作,我编写了以下代码:

int main (){
  char str[] ="- This, a sample string.";
  printf("str address: %p, ends on:  %p \n", str, str+strlen(str));
  printf ("Splitting string \"%s\" into tokens:\n",str);
  char * pch;
  pch = strtok (str," ,.-");
  while (pch != NULL){
    printf ("pch: %7s,  address: %p\n",pch, pch);
    pch = strtok (NULL, " ,.-");
  }
  return 0;
}

执行上述程序(每次运行时地址可能不同):

~$ ./a.out 
str address: 0x7fff96958d50, ends on:  0x7fff96958d68 
Splitting string "- This, a sample string." into tokens:
pch:    This,  address: 0x7fff96958d52
pch:       a,  address: 0x7fff96958d58
pch:  sample,  address: 0x7fff96958d5a
pch:  string,  address: 0x7fff96958d61

注意: pch地址来自/ str地址范围内。

同样在您的代码中,分配给newNode->Data->FName = strtok(input," ");函数中的addOrdered()newNode->Data->FName中的内存地址值是input中的processFile(),您最后在newNode->Data->FName函数中释放所以void addOrdered(Node ** Head,char * input){ printf("\nInput: %s\n",input); // some code here step-2 newNode->Data->FName = strtok(input," "); <--"assign memory" ^ // Some code here | } | | void processFile(Node ** Head, FILE * fd){ | step-1 char * input = malloc(sizeof(char)*SIZE); <-|----"Allocate memory" while(fgets(input,SIZE,fd) != NULL){ | addOrdered(Head,input); ----------------- } step-3 free(input); <-----------------------------------"Free memory" } So, "What is assign to newNode->Data->FName becomes invalid" 变为无效且您的代码以未定义的行为运行

\0

第二,你应该从缓冲区中的文件中读取少一个字符,为空fgets(input, SIZE-1, fd) 保留空格。

{{1}}