C 在另一个动态分配的数组中释放一个动态分配的数组

C 在另一个动态分配的数组中释放一个动态分配的数组,c,pointers,struct,free,C,Pointers,Struct,Free,假设我有下面这个简单的例子 #include <stdlib.h> #include <stdio.h> struct x { int* p; }; typedef struct y { x* foo; }real; void doSomething(); int main() { doSomething(); getchar(); return 0; } void doSomething() { real* tmp

假设我有下面这个简单的例子

#include <stdlib.h>
#include <stdio.h>
struct x {
    int* p;
};

typedef struct y {
    x* foo;
}real;

void doSomething();

int main() {
    doSomething();
    getchar();
    return 0;
}

void doSomething() {
   real* tmp = (real*)malloc(sizeof(real));
   tmp->foo = (x*)malloc(sizeof(x));
   free(tmp->foo);
   free(tmp);
}
#包括
#包括
结构x{
int*p;
};
类型定义结构{
x*foo;
}真实的;
无效剂量();
int main(){
doSomething();
getchar();
返回0;
}
无效剂量测定法(){
real*tmp=(real*)malloc(sizeof(real));
tmp->foo=(x*)malloc(sizeof(x));
免费(tmp->foo);
免费(tmp);
}
在释放“外部”分配的内存之前,是否需要释放内部分配的指针


第二行是否会处理第一个分配的内存…我的假设是否定的(它仍将保留在堆上,我假设需要保持这种方式)。

第一个malloc将只分配空间来容纳
y
的成员。删除它只会删除分配的空间。这与你以后的分配无关。所以,是的,你的假设是正确的。

你可以遵循这个简单的规则,每个MALOC调用都应该有一个相应的免费调用,否则就认为内存没有释放。free的参数必须是相应malloc返回的值。此外,最好在将指针传递到free之前进行空检查


在您的示例中,
struct real
struct x
作为其成员,而
struct x
又将
int*p
作为其成员。在您的真实代码中,您还必须为
p
分配内存,并在使用完毕后释放内存。

只需添加我的两分钱来详细说明为什么部分

让我们先陈述两个概念

  • 您需要
    free()
    内存分配器函数分配的每个内存,以避免内存泄漏

  • 您需要将由
    malloc()
    或family返回的确切指针传递到
    free()
    。它们没有存储任何层次结构信息(如“结构成员”类型,每个分配都是单独的)

  • 因此,要访问内部指针成员
    foo
    ,必须访问(取消引用)外部指针
    tmp

    现在,如果您首先
    free()
    外部指针
    tmp
    之后,访问该free-d内存是无效的调用。因此,您无法到达内部指针以在其上调用
    free()
    。它保持已分配状态,并导致内存泄漏


    这就是为什么,您必须开始从内向外释放内存。

    我可能认为free足够聪明,可以查看它的任何成员是否有更多分配的内存…谢谢您注意,在
    struct y
    中,您指的是类型
    x
    ,但在C中,这不是
    struct x
    指定的类型。在定义了<代码>结构x>代码>之后,只有C++定义了类型<代码> x>代码>;C使类型
    x
    保持未定义,直到使用
    typedef struct x。这意味着你的代码不应该用C编译器编译——但是,尽管C标签,你可能还是使用C++编译器来编译代码。(也许编译器是MS VisualStudio编译器,在那个时候)你是正确的……它是VSR中的C++编译器,答案是“是”和“否”;在释放外部之前,您需要释放内部分配的内存(因为在释放外部之后,您不能通过外部引用内部指针)。决定要做什么变得很棘手。如果是C++代码,就不应该使用<代码> MARROCK()/<代码>和<代码> For()/代码> -如果您不使用自动处理内存分配的类型,则使用<代码>新< /COD>和<代码>删除< /代码>。如果不是C++代码,它就不能编译。如果是C++代码,则需要从<代码> MARROCK()/<代码>中进行强制转换(假设您使用<代码> MARROCURE())/COD>如果是C,你就不需要石膏,尽管如果你小心的话,石膏不会造成太大的伤害。哇!。此外,如果一个给定的
    p
    可能在您的
    real
    x
    集合中保持未分配状态,您可能希望通过检查确保
    p
    不是
    NULL
    (例如
    If(p)free(p);
    )来保护您的
    free
    。(杰伊,我知道你知道,这是对提问者)这个答案似乎暗示,任何有关所需的<代码>免费<代码>将不同,如果使用C++ -它不是'T.DaviC.RANKIN和ToFro,希望我已经在最近的编辑中发表了你的评论。谢谢你的评论。:)