代码之家  ›  专栏  ›  技术社区  ›  Carpetfizz

非动态数组何时在结构中释放

  •  3
  • Carpetfizz  · 技术社区  · 7 年前

    struct

    typedef struct  {
        int id;
        double c[2];
        double p[4][2];
    } Detection;
    

    Detection* create_detection(int i) {
        Detection* detection = (Detection*) malloc(sizeof(Detection));
        detection->id = i;
        return detection;
    }
    

    如您所见,结构本身是动态分配的。我正试着为它写一个析构函数,这就是我到目前为止所拥有的。

    void destroy_detection(Detection* detection) {
        free(detection);
    }
    

    这个免费吗 c p

    4 回复  |  直到 7 年前
        1
  •  5
  •   Zalman Stern    7 年前

    这里只有一个分配。这个 c p 字段没有单独的分配。一般规则是每次调用 malloc free . 编写的析构函数就是所需的全部。如果在结构内部有其他动态分配的指针,那么 可能需要通话。

    请注意 p sizeof(Detection) . 在C++中,字段可以有自己的构造函数,可以进行动态分配,但它们通常也会从编译器在父析构函数中生成的代码中自动析构函数。

    C有可变长度数组(VLA),但它们不能在结构中声明,只能在函数参数列表或函数内的块中声明。

        2
  •  3
  •   n0rd    7 年前

    我想明确说明其他答案中隐含的重要部分:

    malloc 不知道它为什么分配内存。

    它接收字节数作为输入,并返回一个指针,该指针后面至少有那么多字节可寻址。

    sizeof(Detection) 88 . 所以 程序员有责任以某种方式解释该内存(编译器有责任帮助以正确的方式在内存中布局结构成员,并生成适当的代码,给定指向内存的指针和成员名称,它将计算该内存中的适当偏移量以访问该成员数据)-在代码中,您将该地址分配给指向 Detection 结构。您也可以尝试将其分配给指向另一个结构的指针,根据结构大小和分配的内存量,它可能工作,也可能不工作(如程序崩溃和/或擦除计算机上的所有数据)。

    所以 马洛克 ,不知道它为包含数组的结构分配内存。它只分配连续的内存区域,如果编码正确(即,传递给 )足以包含类型为的结构 侦查

    我们可以修改一下你的代码(我有点作弊,因为在我的机器上 long long double 碰巧是一样的,不要这样做):

    #include <stdlib.h>
    #include <stdio.h>
    
    typedef struct {
        int id;
        double c[2];
        double p[4][2];
    } Detection;
    
    int main()
    {
        size_t size = sizeof(Detection);
        printf("sizeof(Detection) = %u\n", size);
        Detection *detection = malloc(size);
        detection->id = 0x01020304;
        *(long long *)(&detection->c[0]) = 0x1011121314151617;
        *(long long *)(&detection->c[1]) = 0x18191A1B1C1D1E1F;
        *(long long *)(&detection->p[0][0]) = 0x2021222324252627;
        *(long long *)(&detection->p[0][1]) = 0x28292A2B2C2D2E2F;
        *(long long *)(&detection->p[1][0]) = 0x3031323334353637;
        *(long long *)(&detection->p[1][1]) = 0x38393A3B3C3D3E3F;
    
        *(long long *)(&detection->p[2][0]) = 0x4041424344454647;
        *(long long *)(&detection->p[2][1]) = 0x48494A4B4C4D4E4F;
        *(long long *)(&detection->p[3][0]) = 0x5051525354555657;
        *(long long *)(&detection->p[3][1]) = 0x58595A5B5C5D5E5F;
    }
    

    0x01097018

    0x01097008  01 00 00 00 58 00 00 00 4e 00 00 00 fd fd fd fd  ....X...N...ýýýý
    ======== detection starts here =========
    0x01097018  04 03 02 01 cd cd cd cd 17 16 15 14 13 12 11 10  ....ÍÍÍÍ........
    0x01097028  1f 1e 1d 1c 1b 1a 19 18 27 26 25 24 23 22 21 20  ........'&%$#"! 
    0x01097038  2f 2e 2d 2c 2b 2a 29 28 37 36 35 34 33 32 31 30  /.-,+*)(76543210
    0x01097048  3f 3e 3d 3c 3b 3a 39 38 47 46 45 44 43 42 41 40  ?>=<;:98GFEDCBA@
    0x01097058  4f 4e 4d 4c 4b 4a 49 48 57 56 55 54 53 52 51 50  ONMLKJIHWVUTSRQP
    0x01097068  5f 5e 5d 5c 5b 5a 59 58
    

    从内存中的值可以很容易地看到结构在内存中的布局,可以注意到数组嵌入到内存布局中。

    free 也完全不知道传递给它的指针的另一端是什么类型的结构。它只是接收到一个[据称]之前由 马洛克 (a) void * )并且知道如何将其作为内存块(而不是某种类型的结构)释放。除了将内存标记为“未使用”之外,没有任何类型的“破坏”发生。

    我又增加了16字节的内存 马洛克 演示如何 58 88 -它是分配的内存大小

    size + 42 到a ,它仍然是正确的程序,只会浪费内存。

        3
  •  1
  •   gsamaras    7 年前

    这个免费吗 c p

    阵列 c p 是静态分配的,这意味着


    经验法则:呼叫 free() malloc() .

    在这里,动态分配内存一次,因此必须只取消分配该动态内存一次。

        4
  •  1
  •   doron    7 年前

    的内存 c p 在结构中内联分配。这是因为 c p

    造成混淆的原因是数组有时会衰减为指针,反之亦然。这方面的一个例子是 double* ptr = c double* ptr = &c[0] ( 是一个数组)。指针衰减在访问数组时发生,在定义数组时不会发生。