我无法理解一些free()行为。
int* ptr1 = (int*)malloc(sizeof (int)*10);
int* ptr2 = ptr1;
free(ptr2);
free(ptr2)
是否会根据需要删除我的数组?
如果我这样做:
int** ptr1 = (int**)malloc(sizeof (int)*10);
int* ptr2 = (int*)malloc(sizeof (int));
*ptr2 = 10;
ptr1[0] = ptr2;
free(ptr1);
这段代码是否正确? free(ptr1)
还会删除ptr2的空间吗?
由于
答案 0 :(得分:3)
分别是和否。
另请注意,第二个示例中的malloc(sizeof(int)*10);
将起作用,但它不一定会为十个指针分配空间。
为了解释第一个例子中发生的事情,在分配给ptr2
之后,你有这样的事情:
+------+ | ptr1 | ---\ +------+ \ +----------------------------+ >---> | memory allocated by malloc | +------+ / +----------------------------+ | ptr2 | ---/ +------+
两个变量都包含相同的值,即malloc
返回的指针,因此您可以使用其中任何一个来访问分配的内存。
对于第二个问题,你所拥有的是这样的:
+---------+---------+---------+-----+ | ptr1[0] | ptr1[1] | ptr1[2] | ... | +---------+---------+---------+-----+ | | v +----------------------------+ | memory allocated by malloc | +----------------------------+ ^ | | +------+ | ptr2 | +------+
释放ptr1
只释放内存的内存指针时,ptr2
指向的内存仍然存在,可通过ptr2
访问。
答案 1 :(得分:2)
malloc
和free
不了解您的数据结构。他们所知道的只是一堆字节。
作为一般规则,您的malloc
和free
来电之间应该存在一对一的关系。 (有很多例外,但这是一个很好的一般规则。)
对free
的单个调用永远不会同时释放两个由malloc
调用分配的单独块。
所以,正如其他人所说,你的问题的答案是“是”和“否”。
答案 2 :(得分:1)
int* ptr1 = (int*)malloc(sizeof(int)*10);
int* ptr2 = ptr1;
free(ptr2);
没关系,ptr2
包含与ptr1
相同的值,因此您传递给malloc()
的内存为free()
d。
int** ptr1 = (int**)malloc(sizeof(int)*10);
int* ptr2 = (int*)malloc(sizeof(int));
*ptr2=10;
ptr1[0]=ptr2;
free(ptr1);
那不行。您将ptr2
的值存储在ptr1
数组中,但不释放它。你想要:
int** ptr1 = (int**)malloc(sizeof(int*)*10);
int* ptr2 = (int*)malloc(sizeof(int));
*ptr2=10;
ptr1[0]=ptr2;
...
free(ptr1[0]);
free(ptr1);
注意我还更改了malloc()
以分配10个指向int
的指针,而不只是10个int
s(可能大小不同)。
最后请注意你在C. don't need to cast the return value from malloc()
我没有为你解决这个问题,因为它本身并不是问题而且与你的问题无关,但它(可以说是)不好的风格。
答案 3 :(得分:0)
free(ptr2)是否会按我的意愿删除我的数组?
我认为这里不能使用delete
这个词。 GNU manual说:
如果您不再需要使用malloc获得的块,请使用 可以自由地使块可以再次分配。
但是free不会自动将指针设置为NULL,因为函数返回类型本身是void
。此外,
释放块会改变块的内容。不要指望 找到任何数据(例如指向链中下一个块的指针) 解冻后块中的块。
我没有激发关于是否应该在释放指针后将指针设置为NULL的争论。但是,我觉得很想发布这个崩溃和烧伤的例子:
#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;
}
<强>输出强>
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)