Linked List Data All The Same

谁说胖子不能爱 提交于 2019-12-24 14:08:13

问题


I'm trying to read in input from a .txt file, and add it into a singly linkedlist. The problem I'm having is the Nodes are being created and connected correctly (I'm getting the correct length), but after adding all the Node, each Data field is the same. I was wondering what the problem is, and how to fix it. Been going at it for awhile!

Add Function:

#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;
        }
}

Processing File:

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

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


    free(input);
}

回答1:


The Bug in your code is: Address assign to newNode->Data->FName becomes invalid once you call free(input) in processFile() function and access the free memory causes an 'Undefined Behavior' at run time.

To correct your code:

instead of simple assignment like:

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

Allocate and Copy in separate memory as below:

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

Actually you were assigning memory address from input address space in addOrdered() and makes free() in processFile() function.

I explain your code elaborate way below:

First read: char * strtok ( char * str, const char * delimiters ); manual:

On a first call, the function expects a C string as argument for str, whose first character is used as the starting location to scan for tokens. In subsequent calls, the function expects a null pointer and uses the position right after the end of last token as the new starting location for scanning.

Return Value

A pointer to the last token found in string. A null pointer is returned if there are no tokens left to retrieve.

It doesn't sends a new memory but memory from input that you lately free(). To understand strtok() function work I written following code:

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;
}

An execution of above program (address can be different at each run):

~$ ./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

Notice: pch address are from/within str address scape.

Similarly in your code, assign to newNode->Data->FName = strtok(input," "); in addOrdered() function. memory address value at newNode->Data->FName is in/from input that you latterly free in processFile() function So newNode->Data->FName become invalid and your code runs as undefined behavior

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"

Second, you should read one less char from file in buffer, keep space for null \0.

fgets(input, SIZE-1, fd)



回答2:


strtok returns A pointer to the last token found in string. A null pointer is returned if there are no tokens left to retrieve. You need to do something like pch = strtok(input," ");



来源:https://stackoverflow.com/questions/15847194/linked-list-data-all-the-same

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!