Hi everybody o/.

I'm studing Linked List in C. I made two functions: add ( add data on the list) and destroy (destroy the list). For now, it's just this two functions that i need, but the function destroy doesn't works well. When I call the function destroy only the first two nodes are destroyed and I can't find out why the others not.

If I call display after destroy, the display continues showing the data after the second node.

Can anyone explain me what I'm doing wrong?

Here my complete code:

/*
 * File:   main.c
 * Author: donda
 *
 */

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

struct t_ddclist {
   int index;
   char value[256];
   struct t_ddclist *next;
};

typedef struct t_ddclist ddclist;


ddclist *createDDCList();
int addDDCList(ddclist *list, char *value);
void destroyDDCList(ddclist *list);
void displayDDCList(ddclist *list);

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

   ddclist *myList = createDDCList();

   if (!myList) {
       printf("Error on create list\n");
       exit(-1);
   }

   addDDCList(myList,"Test1");

   addDDCList(myList,"Test2");

   addDDCList(myList,"Test3");

   addDDCList(myList,"Test4");

   addDDCList(myList,"Test5");

   addDDCList(myList,"Test6");

   displayDDCList(myList);

   destroyDDCList(myList);
   
  return (EXIT_SUCCESS);
}

ddclist *createDDCList() {

   ddclist *newList = NULL;

   newList = malloc(sizeof (ddclist));

   if (!newList) {
       return NULL;
   }

   newList->index = -1;
   newList->next = NULL;
   if (!newList->value) {
       return NULL;
   }

   return newList;
}

int addDDCList(ddclist *list, char *value) {

   ddclist *addList = NULL;

   addList = createDDCList();

   if (!addList) {
       return -1;
   }

   if (list->index == -1) {
       list->index = 0;
       strcpy(list->value, value);
       return 1;
   }

   ddclist *i, *temp;

   i = list;

   while (i) {
       if (!i->next) {
           temp = i;
       }
       i = i->next;
   }
   addList->index = (temp->index + 1);
   strcpy(addList->value, value);
   temp->next = addList;
   return addList->index;
}


void destroyDDCList(ddclist *list){

   ddclist *p=list;

   while(p!=NULL){
       ddclist *tmp = p->next;
       free(p);
       p=tmp;

   }

void displayDDCList(ddclist *list) {

   ddclist *l = list;

   while (l) {
       printf("Index:%d\nValue:%s\n\n", l->index, l->value);
       l = l->next;
   }
}

}

> Can anyone explain me what I'm doing wrong?

Sure.

> If I call display after destroy, the display continues showing the data after the second node.

Question is, what do you expect?
After destroy, an access to the list invokes an undefined behaviour. That is, once the list is destroyed, Do Not Touch It. Otherwise, your code is quite correct.

Question is, what do you expect?
After destroy, an access to the list invokes an undefined behaviour. That is, once the list is destroyed, Do Not Touch It. Otherwise, your code is quite correct.

I know that the invokes will have an undefined behaviour, and is that what i want.

But look what happens:

Before destroy the call display result:


Index:0 Value:Test1

Index:1 Value:Test2

Index:2 Value:Test3

Index:3 Value:Test4

Index:4 Value:Test5

Index:5 Value:Test6


Then, after calling destroy:

Index:168899499 Value: // <-- cool, here was destroyed.

Index:169482400 Value: // <-- cool, here was destroyed.

Index:2 Value:Test3 // <-- From here, the data continues exist. Why?

Index:3 Value:Test4

Index:4 Value:Test5

Index:5 Value:Test6

Index:2 Value:Test3 // <-- From here, the data continues exist. Why?

struct t_ddclist {
   int index;
   char value[256];
   struct t_ddclist *next;
};
ddclist *createDDCList() {
   ddclist *newList = NULL;
   newList = malloc(sizeof (ddclist));
   if (!newList) {
       return NULL;
   }

   newList->index = -1;
   newList->next = NULL;
   if (!newList->value) {
       return NULL;
   }

   return newList;
}

At every createDDCList, a single block of memory is allocated. At destroyDDCList, each of them is deallocated. Deallocation loosely speaking means that the system may reuse them at its leisure. It happens so that some parts of two first blocks did get reused. The rest happened to remain intact.
Make an experiment: just for fun, declare your structure as

struct t_ddclist {
   int index;
   struct t_ddclist *next;
   char value[256];
};

and rerun your program. Explain the difference.


At every createDDCList, a single block of memory is allocated. At destroyDDCList, each of them is deallocated. Deallocation loosely speaking means that the system may reuse them at its leisure. It happens so that some parts of two first blocks did get reused. The rest happened to remain intact.
Make an experiment: just for fun, declare your structure as

struct t_ddclist {
   int index;
   struct t_ddclist *next;
   char value[256];
};

and rerun your program. Explain the difference.

Understood.

This application will reading a buffer file, and manipulate the data read and write on another file. Then my worry was because if this data even after destroy list continues on memory, the memory size used for the application will increase time after time and after hours executing the memory size used will be bigger, and I don't wanna this.

So, my question is: Like you said, after use free() the application allow the use of this allocation memory for another thing, so my memory will not increase time after time of use?

If was increase, why if I'm using free()?

Thanks for all help.

Hi, so i ran the app all this afternoon and the memory usage doesn't increase like imagine, so it's like you said, the system used the free alloc data for another things and doesn't increase the memory usage.

Thanks for all help.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.