Home > OS >  Why is "free" saying this that my pointer is invalid?
Why is "free" saying this that my pointer is invalid?

Time:12-31

while(n >= 0);
    node * point = malloc(sizeof(node));
    point = create(number, n);

    //show(point);

    //free memory
    while(point != NULL)
    {
        node *tmp = point->next;
        free(point);
        point = tmp;
    }

}

node * create(int data[], int len)
{
    node * list_head;
    node * list;
    for (int i = 0; i < len; i  )
    {
        if(i == 0)
        {
            list_head = malloc(sizeof(node));
            list = malloc(sizeof(node));
            list_head->value = data[0];
            list_head->next = list;
        }
        else
        {
            list->value = data[i];
            list->next = malloc(sizeof(node));
            list->next = NULL;
        }
    }
    return list_head;
}

This code is returning an error which is:- free(): invalid pointer Aborted | Why is my code not freeing the memory that I allocated. Is it because I have allocated that in some different function?

CodePudding user response:

The code you posted should be changed to:

while(n >= 0) {
    node * point = create(number, n);

and:

list->next = NULL;

should be changed to

list = list->next;

CodePudding user response:

You harbor a complete misunderstanding of memory management in C. Pointer point to things.

  • Sometimes they are indeterminate (you never established what they point to).
  • Sometimes they point to dynamic things (allocated using heap functions like malloc)
  • Sometimes they point to automatic things (int i; int *p = &i;)
  • And sometimes they intentionally point to nothing (e.g. NULL)

Lines like this:

node * point = malloc(sizeof(node));
point = create(number, n);

are a recipe for a guaranteed memory leak.

  1. node * point = malloc(sizeof(node)); allocates memory using malloc, storing the resulting address in the pointer point.
  2. point = create(number, n); invokes some function create, storing whatever is returned in the same pointer point, thereby orphaning the very memory that was just allocated in (1). That memory now has no pointer hold the address it had prior, and therefore the memory is leaked .

See the problem? The same problem transpires here further in the code:

list->next = malloc(sizeof(node));
list->next = NULL;

C isn't Java. Not everything needs to be new'd (or malloc'ed) just because a pointer is involved. For example:

int i = 42;
int *p1 = &i; // p1 now holds the address of the 'i' variable.
int *p2 = p1; // p1 and p2 both now hold the address of the 'i' variable.
p1 = NULL;    // p1 no longer points to 'i'
p2 = p1;      // p2 no longer points to 'i' now either.

A debugger, and single-stepping through your code to monitor variables, their values, and if they're pointers, what they point to (if anything) is an incredible tool, and I strongly suggest you embrace one soon. I don't know what site/text you're learning this from, but I strongly suggest you utilize another reference, preferably one with a decent reputation of actually teaching something (and that includes switching professors if warranted).

That said, creating a linked list by forward-chaining is straight forward.

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

// our node
typedef struct node node;
struct node
{
    int value;
    node *next;
};

// create a simple linked list from an array
node *create_list(const int ar[], int len)
{
    node *list = NULL, *cur = NULL;

    for (int i=0; i<len;   i)
    {
        node *p = malloc( sizeof *p );
        if (p == NULL)
        {
            perror("Failed to allocate new list node");
            break;
        }
        p->value = ar[i];
        
        if (cur)
        {
            cur->next = p;
        }
        else
        {
            list = p;
        }
        cur = p;
    }

    if (cur)
    {
        cur->next = NULL;
    }
    
    return list;
}

void free_list(node *list)
{
    while (list)
    {
        node *tmp = list;
        list = list->next;
        free(tmp);
    }
}

void print_list(const node *list)
{
    while (list)
    {
       printf("%d ", list->value);
       list = list->next;
    }
    fputc('\n', stdout);
}

int main()
{
    int ar[] = { 1,2,3,4,5,6,7,8,9,10 };
    node *list = create_list(ar, sizeof ar / sizeof *ar);
    print_list(list);
    free_list(list);
    return EXIT_SUCCESS;
}

Output

1 2 3 4 5 6 7 8 9 10
  • Related