Reputation: 505
I'm learning C and trying to figure out an elegant way to free my pointers at the end of the execution.
After hours debugging and experimenting different things with the following code, I couldn't manage to figure out what I was doing wrong:
int ClosePointers(char *pointersToClose[], int arraySize) {
int index;
for(index = 0; index < arraySize; index++) {
char *pointer = pointersToClose[index];
free(pointer);
}
return (0);
}
int main(int argc, char *argv[]) {
char *pointersToClose[4];
char *pointer1;
char *pointer2;
char *pointer3;
char *pointer4;
pointersToClose[0] = pointer1;
pointersToClose[1] = pointer2;
pointersToClose[2] = pointer3;
pointersToClose[3] = pointer4;
pointer1 = malloc(10);
pointer2 = malloc(10);
pointer3 = malloc(10);
pointer4 = malloc(10);
/*some important code here using the pointers*/
ClosePointers(pointersToClose, 4);
return 0;
}
I'm getting the following error: * glibc detected * /home/workspace/Debug/Test-POC: free(): invalid pointer: 0x00000038ce7b9850 ***
Could you help me out pointing what I'm doing wrong?
Upvotes: 3
Views: 229
Reputation: 164
In order to free a pointer you must first have allocate memmory for it. You are going to free pointers that are never allocated. Try the following code to understnd what you did wrong
int AllocatePointers(char *pointersToClose[], int arraySize) {
int index;
for(index = 0; index < arraySize; index++) {
pointersToClose[index] = malloc(50*sizeof(char));
}
return (0);
}
int main(int argc, char *argv[]) {
char *pointersToClose[4];
char *pointer1;
char *pointer2;
char *pointer3;
char *pointer4;
pointersToClose[0] = pointer1;
pointersToClose[1] = pointer2;
pointersToClose[2] = pointer3;
pointersToClose[3] = pointer4;
AllocatePointers(pointersToClose, 4);
/*some important code here using the pointers*/
ClosePointers(pointersToClose, 4);
return 0;
}
Upvotes: 0
Reputation: 24812
Could you help me out pointing what I'm doing wrong?
You should use free()
only on pointers that you allocated on the heap using the malloc()
function.
What happens, is that within the heap (a reserved memory space), the length you gave as parameter to the malloc()
function is allocated for your use, and it returns the address to the first word of that memory space so it can be assigned to a pointer.
When you use free()
, it's deallocating that memory space so it can be reused.
Here, you create pointers variables that points to nothing (actually they point to a random value). So what's happening when you call free()
on those variables is that you try to deallocate some random memory space that is not within the managed space, called the heap. As those addresses are unlikely to be allocated by malloc()
, the free()
function cannot know what to do with it, and therefore will return an error!
Read on about what are the stack and the heap to better understand what those are. Also, read the C programming language book by Kernighan and Ritchie where it's all well explained.
Upvotes: 1
Reputation: 134336
In your code. pointer1
is unitialized. It points to invalid memory. Passing that to free()
invokes undefined behavior.
Quoting C11
, chapter §7.22.3.3, (emphasis mine)
The
free
function causes the space pointed to byptr
to be deallocated, that is, made available for further allocation. Ifptr
is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call tofree
orrealloc
, the behavior is undefined.
You need to either
NULL
(null-pointer
constant)malloc()
or family to allocate free
-able memory first.That said, pointer2
, pointer3
and pointer4
are undeclared in your code but probably that's a typo, so we can overlook it.
Upvotes: 0
Reputation: 223937
You're calling free
on those pointers, but you never allocate any memory to them with malloc
. In fact, the pointers you are trying to free
are uninitialized, so they could contain anything.
When you set the values of pointersToClose
, you're assigning the current value of pointer1
, pointer2
, etc., not whatever value they may contain when "some important code here using the pointers" runs.
Passing a pointer value to free
that was not returned by malloc
/realloc
/calloc
results in undefined behavior.
If you want to do this, try putting the address of each of the pointers in question in your array.
int ClosePointers(char **pointersToClose[], int arraySize) {
int index;
for(index = 0; index < arraySize; index++) {
char **pointer = pointersToClose[index];
free(*pointer);
}
return (0);
}
int main(int argc, char *argv[]) {
char **pointersToClose[4];
char *pointer1;
char *pointer2;
char *pointer3;
char *pointer4;
pointersToClose[0] = &pointer1;
pointersToClose[1] = &pointer2;
pointersToClose[2] = &pointer3;
pointersToClose[3] = &pointer4;
/*some important code here using the pointers*/
ClosePointers(pointersToClose, 4);
return 0;
}
Upvotes: 2