I'm having trouble understanding some of the free() behavior.
int* ptr1 = (int*)malloc(sizeof (int)*10);
int* ptr2 = ptr1;
free(ptr2);
Is the free(ptr2)
going to delete my array as I want ?
What if I do :
int** ptr1 = (int**)malloc(sizeof (int)*10);
int* ptr2 = (int*)malloc(sizeof (int));
*ptr2 = 10;
ptr1[0] = ptr2;
free(ptr1);
Is this code correct ? Will free(ptr1)
will also delete the space of ptr2 ?
Thanks
Yes and no, respectively.
Also note that malloc(sizeof(int)*10);
in the second example will work, but it will not necessarily allocate space for ten pointers.
To explain what happens in the first example, after the assignment to ptr2
you have something like this:
+------+ | ptr1 | ---\ +------+ \ +----------------------------+ >---> | memory allocated by malloc | +------+ / +----------------------------+ | ptr2 | ---/ +------+
Both variables contain the same value, the pointer returned by malloc
, so you can use either of them to access the allocated memory.
For the second question, what you have is something like this:
+---------+---------+---------+-----+ | ptr1[0] | ptr1[1] | ptr1[2] | ... | +---------+---------+---------+-----+ | | v +----------------------------+ | memory allocated by malloc | +----------------------------+ ^ | | +------+ | ptr2 | +------+
When you free the memory pointer to by ptr1
that only frees that memory, the memory pointed to by ptr2
is still there and accessible through ptr2
.
malloc
and free
do not know about your data structures. All they know about is blobs of bytes.
As a general rule, there should be a one-to-one relationship between your malloc
and free
calls. (There are plenty of exceptions, but it's a good general rule.)
It is never the case that a single call to free
will simultaneously free two separate blocks allocated by two calls to malloc
.
So, as others have said, the answers to your questions are "Yes" and "No".
int* ptr1 = (int*)malloc(sizeof(int)*10);
int* ptr2 = ptr1;
free(ptr2);
That is fine, ptr2
contains the same value as ptr1
, and thus the memory you passed to malloc()
is free()
d.
int** ptr1 = (int**)malloc(sizeof(int)*10);
int* ptr2 = (int*)malloc(sizeof(int));
*ptr2=10;
ptr1[0]=ptr2;
free(ptr1);
That is not fine. You are storing the value of ptr2
in the ptr1
array, but not freeing it. You want:
int** ptr1 = (int**)malloc(sizeof(int*)*10);
int* ptr2 = (int*)malloc(sizeof(int));
*ptr2=10;
ptr1[0]=ptr2;
...
free(ptr1[0]);
free(ptr1);
Note I have also changed the malloc()
to allocate 10 pointers to int
, not merely ten int
s (which may not be the same size).
Finally note that you don't need to cast the return value from malloc()
in C. I haven't fixed that for you as it is not a problem in itself and is unrelated to your question, but it is (arguably) bad style.
Is the free(ptr2) going to delete my array as I want ?
I think the term delete
cannot be used here. The GNU manual says :
When you no longer need a block that you got with malloc, use the function free to make the block available to be allocated again.
However free doesn't set pointer automatically to NULL because the function return type itself is void
. Also,
Freeing a block alters the contents of the block. Do not expect to find any data (such as a pointer to the next block in a chain of blocks) in the block after freeing it.
I am not spurring a debate on whether you should set the pointer to NULL after freeing it. However,I felt tempted to post this example which crashes and burns :
#include<stdio.h>
#include<stdlib.h>
int main()
{
int* ptr1 = malloc(sizeof(int)*10);
int* ptr2 = ptr1;
free(ptr2);
if(ptr2!=NULL)
{
printf("ptr is %p\n",ptr2); // still printf
printf("Enter a number for ptr2 :");
scanf("%d",ptr2);
printf("Value pointed to by ptr2 : %d\n",*ptr2);
printf("Value pointed to by ptr1 : %d\n",*ptr1);
}
else
printf("Ptr2 pointed to null");
printf("Size of ptr1 : %d\n",sizeof(ptr1));
if(ptr1==NULL)
printf("ptr1 NULL\n");
printf("Enter a number for ptr1 :");
scanf("%d",ptr1);
printf("Value pointed to by ptr1 : %d\n",*ptr1);
printf("Value pointed to by ptr2 : %d\n",*ptr2);
free(ptr1);
if(ptr1==NULL)
printf("ptr1 freed\n");
return 0;
}
Output
ptr is 0x1c92010
Enter a number for ptr2 :4
Value pointed to by ptr2 : 4
Value pointed to by ptr1 : 4
Size of ptr1 : 8
Enter a number for ptr1 :1
Value pointed to by ptr1 : 1
Value pointed to by ptr2 : 1
*** glibc detected *** ./testp: double free or corruption (fasttop): 0x0000000001c92010 ***
Segmentation fault (core dumped)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.