[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 331
  • Last Modified:

linked list string display problem

Hi,
i've got a linked list here, this is a assignment just to let you know :)
i need to read a file, line by line, write each line into the heap and then
print it out again in reverse order.

sample input:
aaaa
ssss
dddd

sample output:
dddd
ssss
aaaa

i'll worry about the reverse output later, first i have a little problem.
---------
the debugger tells me that all the lines are getting written into the heap as they should,
however, within my display function something happens and its calling the data from the same
address all the time.
i'm pretty new to all this, so keep it simple :)

my code:

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

typedef struct node {
          char *m_Num;
          struct node *next;
          } NODE;

typedef struct list {
          NODE *front;
          NODE *cursor;
          } LIST;

LIST list = {NULL, NULL};
void Insert(LIST *list, char* item);
void Display(LIST *list);

int main(int argc, char **argv) {

      int i;
      char buffer[1024];
      FILE *stream;
         LIST *list;
         list = malloc (sizeof(LIST));
    list->front = NULL;
      list->cursor = NULL;

      i = 0;
        if( (stream = fopen( argv[1], "r" )) != NULL ){
            while (fgets (buffer, sizeof(buffer), stream)){
                  Insert(list, buffer);
                  i++;
            }
            fclose(stream);
               }
      Display(list);
      return 0;
};


void Insert(LIST *list, char *item){
      
   NODE* tmp = malloc(sizeof(NODE)+1);

   tmp->m_Num = item;    
   tmp->next = list->front;
   list->front = tmp;
   list->cursor = tmp;

   return;
}

void Display(LIST *list){
   list->cursor = list->front;

   while(list->cursor != NULL){
      printf("List item: %s\n", list->cursor->m_Num);
      list->cursor = list->cursor->next;
   }
}

any help is greatly apprechiated.

thanks
nOOgz

0
nOOgz
Asked:
nOOgz
  • 2
1 Solution
 
nOOgzAuthor Commented:
I think that there is some problem already while writing the data.
i have 2 screenshots of the debugger here:

so this is after the first loop. the line 'aaaaaaaaaaaaaaaaaa' should be already written into
the heap, and its address should be in front->next
http://www.noogz.org/front-mnum1.jpg

but as you see here, front->next contains the new line already
http://www.noogz.org/front-next-mnum.jpg

maybe i'm confusing things here. i'm still lacking some basic understanding of that nested pointer struct thing.

how i understood this, it shouldnt be any harder like:
getting a line, allocate memory for that line and getting the address of that memory, writing the data to that address,
pointing the 'next' to the address of the current line.  hmz..



0
 
vadim_tiCommented:
i think your insert function has a problem:

void Insert(LIST *list, char *item){
     
   NODE* tmp = malloc(sizeof(NODE));  // +1 - you do not need it, but it is not a problem


// problem is here:
/* -----------------------------
   tmp->m_Num = item;    
--------------------------------*/

{
  char *p = malloc(strlen(item)+1);
 strcopy(p, item);
tmp->m_Num = p;
// in your code you save the same address buffer, so you will always display last line of the file
}

   tmp->next = list->front;
   list->front = tmp;
   list->cursor = tmp;

   return;
}
0
 
ankuratvbCommented:
vadim_ti is right about you using the address of the variable 'buffer' every time and every time the user enters a string ,you overwrite the contents of buffer.

So when the insertion ends,you have the last string's value in buffer and all your nodes point to buffer,so it'll always print the last node's value.

I'd suggest,change your struct defn to store a char array rather than a pointer.

ChaNGE:

typedef struct node {
         char *m_Num;
         struct node *next;
         } NODE;

TO

typedef struct node {
         char m_Num[100];//declare an array of sufficient size
         struct node *next;
         } NODE;

or if you do want to allocate memory dynamically,do:

void Insert(LIST *list, char *item){
   
NODE* tmp = malloc(sizeof(NODE));  // +1 - you do not need it, but it is not a problem
tmp->m_Num= malloc(strlen(item)+1);
strcpy(tmp->m_Num, item);
tmp->next = list->front;
list->front = tmp;
list->cursor = tmp;
return;

}

This way you know that the allocated memory is pointed to by m_Num,so at the time of freeing,you can call.

free(tmp->m_Num);

0
 
nOOgzAuthor Commented:
great, thanks.

vadim_t: your solution works just fine. thank you for that.

ankuratvb: thanks yours helped me for some understanding as well, also thank you. i'd llike to put yours into 'assisted answer' but i can't find how :)

thanks guys.

take care.
nOOgz
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now