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.
node * point = malloc(sizeof(node));
allocates memory usingmalloc
, storing the resulting address in the pointerpoint
.point = create(number, n);
invokes some functioncreate
, storing whatever is returned in the same pointerpoint
, 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