简体   繁体   English

如果两个指针指向同一个memory地址,是只需要使用free(ptr)一次还是两次?

[英]If two pointers point to the same memory address, do you only need to use free(ptr) once or twice?

Say we have a struct...假设我们有一个结构......

struct node{
    int data;
    struct node *next;
};

struct node *new_node = malloc(sizeof(node));

struct node *temp_node = new_node;

If I use free...如果我使用免费...

free(temp_node);

Is new_node free as well (since the address no longer exists) or does new_node simply point to NULL (in which case I would need to free new_node as well)? new_node 也是免费的(因为地址不再存在)还是 new_node 只是指向 NULL (在这种情况下我也需要释放 new_node)?

Cheers!干杯!

You don't free pointers but the memory block(s) that you allocated - whose address a pointer points to.您不会释放指针,而是释放您分配的 memory 块 - 指针指向其地址。

With malloc , it returns pointer to a chunk of memory allocated that looks like this:使用malloc ,它返回指向分配的 memory 块的指针,如下所示:

             +--------+
             |        |
new_node --> | 0x1000 |
             |        |
             +--------+

If 0x1000 is the starting address of that block of memory, that's what new_node points to (ie, new_node == 0x1000 ).如果0x1000是 memory 的那个块的起始地址,那就是new_node指向的地址(即new_node == 0x1000 )。

When you assign new_node to temp_node , temp_node points to the same block of memory (ie, temp_node == 0x1000 ):当您将new_node分配给temp_node时, temp_node指向 memory 的同一块(即temp_node == 0x1000 ):

             +--------+
             |        |
new_node --> | 0x1000 | <-- temp_node
             |        |
             +--------+

But there's just one block of memory that you have allocated.但是您只分配了一块 memory。 So once you free it via either pointer, the other is automatically invalidated and you are no longer allowed access that block of via either pointer.因此,一旦您通过任一指针释放它,另一个将自动失效,并且您不再被允许通过任一指针访问该块。

In the same way, you can assign it to any number of pointers but as soon as it's free'd via one pointer, it's done.同样,您可以将它分配给任意数量的指针,但只要它通过一个指针释放,它就完成了。 That's why care is needed when copying pointers around (because if you free one, it may still be inadvertently used).这就是为什么在复制指针时需要小心(因为如果你释放一个指针,它可能仍会被无意使用)。

PS: Free'd pointer may or may not point to NULL afterwards - it's simply undefined behaviour to access free'd memory. PS:之后,Free'd 指针可能指向也可能不指向 NULL - 访问 free'd memory 只是未定义的行为。

There are plenty of exceptions, but as a general rule, there should be exactly one call to free for every call to malloc .有很多例外,但作为一般规则,每次调用malloc都应该有一个free调用。

When you assign one pointer variable to another, you are copying the pointer value -- you are not allocating more memory.当您将一个指针变量分配给另一个时,您是在复制指针值——您并没有分配更多的 memory。 So a pointer copy does not imply the need for a second call to free .因此,指针副本并不意味着需要第二次调用free

The way to think about is like: pointers point to a memory location.思考的方式是这样的:指针指向一个 memory 位置。 free() returns memory pointed to by a pointer back to the system. free()返回由指向系统的指针指向的 memory。 Thus if you have two pointers - once free is called the memory is returned to the system.因此,如果您有两个指针 - 一旦调用free memory 将返回给系统。 You still have two pointers.你仍然有两个指针。 And they still point to the same memory location.而且它们仍然指向相同的 memory 位置。 It's just now it is not your memory but system's:)只是现在不是你的 memory 而是系统的:)

In short - free as many times as you malloc 'd.简而言之 - free多次malloc 'd。

Because you are freeing memory and I see just one malloc here, you should only free() once.因为您正在释放 memory 而我在这里只看到一个malloc ,所以您应该只free()一次。

In general, for each malloc , there has to be one and only one free .一般来说,对于每个malloc ,必须有一个且只有一个free Otherwise, you will get a double free error.否则,您将收到双重free错误。

For one memory address, you only need to call free once. 1个memory地址,只需要free调用一次。

Once you call free , that tells the operating system that the memory you allocated can be used again.一旦你调用free ,就会告诉操作系统你分配的 memory 可以再次使用。 You do not need to call free on it a second time (and shouldn't, because that's undefined behavior).您不需要再次调用free (也不应该,因为这是未定义的行为)。

A few notes on the code关于代码的一些注释

  • The declarations struct *next and struct *temp_node point to an unnamed struct that has no instances.声明struct *nextstruct *temp_node指向一个没有实例的未命名结构。
  • node is just a structure tag used to name the structure and cannot be used in an expression like this malloc(sizeof(node)) . node只是用于命名结构的结构标记,不能在这样的表达式中使用malloc(sizeof(node))

If this is what you originally meant:如果这是您最初的意思:

struct node{
  int data;
  struct node *next;
};
struct node * new_node = malloc(sizeof(struct node));
struct node * temp_node = new_node;

Then the answers provided before this post are completely accurate.那么这篇文章之前提供的答案是完全准确的。

#include<stdio.h>
#include<stdlib.h>

struct Node
{
    int data;
    struct Node * next;
}* first=NULL;

int main()
{
    first=(struct Node *)malloc(sizeof(struct Node));
    first->data=5;
    first->next=NULL;

    struct Node * t=first;

    printf("%d",t->data);

    free(first);

    printf(" %d ",t->data);
}

In this scenario though First is freed in main then too t prints the data.在这种情况下,尽管First在 main 中被释放,然后也t打印数据。 Which says that the allocated memory block can be further used for the different allocation but it's still there and can be used if a pointer is pointing to it.这表示分配的 memory 块可以进一步用于不同的分配,但它仍然存在并且可以在指针指向它时使用。

But in case new allocation is made then that memory block may be allocated to the other variable.但是如果进行了新的分配,那么 memory 块可以分配给另一个变量。 Hence after freeing the memory it's behaviour is undefined.因此,在释放 memory 之后,它的行为是未定义的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM