【问题标题】:How to release a struct that wasn't called with malloc?如何释放未使用 malloc 调用的结构?
【发布时间】:2021-02-16 03:36:19
【问题描述】:

假设我有一个这样的结构 node

struct node {
   struct other_struct value;
   int some_num;
}

我看过sn-ps的代码,其中结构可以在不调用malloc的情况下进行初始化,如下所示:

struct node my_node;
my_node.value = NULL;
my_node.some_num = 2;

然后value 可以稍后被分配。但是,我如何释放my_node

【问题讨论】:

  • 您发布的代码无法编译
  • 你无法释放它。而你实际上不需要。如果它是一个局部变量,编译器将负责管理该内存。如果它是静态或全局变量,那么它在整个代码执行过程中仍然有效,并且在进程运行时永远不需要回收它的内存。
  • 如果 value 是您想要指向 malloc 的指针(我不完全明白您的问题),即使您 malloc value 也不必释放 my_node。但是,您可能需要释放 value
  • 可能你的意思是my_node.value = NULL; my_node.some_num = 2;,而不是那里使用-> 运算符?
  • 你必须知道malloc()和朋友分配了哪些内存,才能准确释放。如果您修复代码并稍后分配一个struct other_struct 以通过my_node->value 使用,那么您将需要释放该指针。你不需要释放my_node;它不是由malloc() 分配的,不能被释放。

标签: c pointers malloc free


【解决方案1】:

my_node在栈上分配,一旦超出范围,它的内存就会被自动释放。

如果你想在堆上分配一些东西,使用malloc,它会一直存在直到你释放它。对于你的例子,你会这样做:

struct node *my_node = malloc(sizeof(struct node));
my_node->some_num = 2;
// Sometime later

free(my_node);

如果您 malloc (只要您传递正确的大小)或在堆栈上声明,也会为 value 字段分配空间。 sizeof(struct node) 包含other_struct 的大小。

【讨论】:

  • my_node需要分配的属性(即value)呢?它也会自动分配吗?
  • 是的,即使您执行 malloc。如果您malloc,请传递正确的尺寸。如果value 是指向other_struct 的指针,那么您必须分配它。
  • 自动对象的内存在其生命周期结束时释放,而不是在超出范围时释放。例如,如果将对象的地址传递给子程序,则子程序可以使用该对象;它存在,并且它的内存保留在子例程中,即使对象的名称不在子例程的范围内。自动对象在其关联块执行结束时的生命周期(如函数返回时)。生命周期是在程序执行期间存在一个对象。范围是在源代码中 标识符可见的位置。
【解决方案2】:

目前使用这些代码 sn-ps 你不能真正释放 value 或 my_node,因为它们都是静态变量,如果在你的节点结构中,other_struct 字段是一个指针,那么你可以动态分配一些内存,并将地址保存在该指针中。 完成后,释放指针值。 如果那时,my_node 也是一个指针(我认为这是您想要的),您需要为节点结构分配内存,并将地址保存到指针 my_node。然后,为 other_struct 结构分配一些内存并将其保存到指针值。完成后,您将首先释放 value,然后释放 my_node。

当做这样的事情时,我通常会创建一个小的构造函数/析构函数,它会为我做这一切。忘记释放内部指针(值)而只释放外部指针(mynode)可能太容易了。那么这会导致内存泄漏,因为值仍然会被分配并占用内存空间。

【讨论】:

    【解决方案3】:

    代码:

    struct node {
       struct other_struct value;
       int some_num;
    };
    

    value 定义为struct node 的成员。它是struct node 的一部分。每当创建struct node 时,它将包含名为value 的成员,并且不需要为value 分配其他内存。无论struct node 是自动创建的还是通过malloc 或其他方式创建的,其内存将始终包含value 的内存。

    如果您将其更改为:

    struct node {
       struct other_struct *value;
       int some_num;
    }
    

    那么value 将是一个指向struct other_struct 的指针,您需要为其提供指向的内存。

    在这段代码中:

    struct node my_node;
    my_node.value = NULL;
    my_node.some_num = 2;
    

    对象my_node是自动创建的,你不需要做任何事情来释放它或者它的成员;这将自动发生。你不能使用my_node.value = NULL,因为value是一个结构,而不是一个指针。

    如果结构体定义改变为value是一个指针,那么你可以设置为NULL,或者你可以设置它指向一个现有的对象,或者你可以为它分配内存并设置它指向分配的内存。如果为它分配内存,则应确保稍后释放内存(除非您有意将其保留到程序执行结束时不释放它,并且您在一般用户模式下执行 -目的操作系统)。

    【讨论】:

      【解决方案4】:

      你没有释放它...它被销毁,当它被声明的块被程序放弃时。

      假设这个变量是在函数体块的开头定义的。当函数被调用时,函数会创建这个变量,因为它是一个本地变量。当函数终止时,所有局部变量都被销毁,所以它是你的局部结构。

      如果您在任何函数中声明这样的变量,那么您的变量具有全局持续时间,并且它是在程序初始化时创建的,并且与程序本身一样存在。

      【讨论】:

        猜你喜欢
        • 2014-12-13
        • 1970-01-01
        • 2011-01-11
        • 1970-01-01
        • 2021-08-29
        • 1970-01-01
        • 2020-08-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多