释放一个等于malloc指针的指针

时间:2016-04-27 16:06:29

标签: c

我无法理解一些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的空间吗?

由于

4 个答案:

答案 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)

mallocfree不了解您的数据结构。他们所知道的只是一堆字节。

作为一般规则,您的mallocfree来电之间应该存在一对一的关系。 (有很多例外,但这是一个很好的一般规则。)

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)