【问题标题】:Array inside a Struct being malloced结构内的数组被分配
【发布时间】:2011-12-16 11:47:34
【问题描述】:

我有以下代码:

#define MAX_NUMBER_OF_FRAMES 10

typedef struct my_frame_header {
    unsigned int ul_Src;
    unsigned int ul_Dest;
} MY_FRAME_HEADER;

typedef struct my_frame {
    MY_FRAME_HEADER x_FrameHeader;
    unsigned char  uc_Frame[3000];
} MY_FRAME;

int main(int argc, char *argv[])
{
    MY_FRAME *px_MyFrames;
    px_MyFrames = (MY_FRAME *)malloc(sizeof(MY_FRAME) * MAX_NUMBER_OF_FRAMES);

    // Use the x_MyFrames variable like an array
    px_MyFrames[0].uc_Frame[0] = 10;

    //free px_MyFrames
    free(px_MyFrames);

    return 1;
}

所有内存都会被成功释放吗?还是我需要在 MY_FRAME 的 Init 函数中使 uc_Frame 成为指针和 malloc 内存?然后在析构函数中为 px_MyFrames 的每个 uc_Frame 释放内存,然后释放 px_MyFrames? (对不起,如果有任何编译器错误,我只是即时写给你基本的想法)。如果我把它放在这里的方式不正确,并且存在内存问题,你能解释一下这些问题可能是什么吗?

【问题讨论】:

  • 欢迎来到 StackOverflow,希望您阅读FAQ

标签: c arrays memory malloc free


【解决方案1】:

因为uc_Frame 是一个数组而不是一个指针,所以这非常有效。由于它是一个数组,因此数据将直接存储在结构中,而结构的大小约为 3008 字节。所以没有必要为uc_Frame 分配任何数据,因为再次它是一个数组而不仅仅是一个指针

会不会是这样的:

typedef struct my_frame {
    MY_FRAME_HEADER x_FrameHeader;
    unsigned int   ul_FrameSize;
    unsigned char *uc_Frame;
} MY_FRAME;

然后您必须动态分配(当然是释放)uc_Frame 的数据,因为它只是一个指针而不是数组。而且它不会存储在结构中,而结构的大小只有大约 16 或 24 字节。

【讨论】:

  • 谢谢,我只是不确定数组是否被正确处理。但是正如你和其他人所提到的,它不需要指针和另一个 malloc/free 就可以很好地工作。
  • @J.C.如果这个(或任何其他)答案是您问题的正确答案,则接受和投票是正确的答案。如果您不知道我在说什么以及这个问答网站是如何运作的,请查看FAQ
【解决方案2】:

是的,调用free会释放内存。

看看这个:

#include <stdio.h>

typedef struct my_frame_header {
    unsigned int ul_Src;
    unsigned int ul_Dest;
} MY_FRAME_HEADER;

typedef struct my_frame {
    MY_FRAME_HEADER x_FrameHeader;
    unsigned char  uc_Frame[3000];
} MY_FRAME;

int main()
{
    printf("%d\n", sizeof(MY_FRAME));
}

运行时会打印 3008。

这意味着当您调用malloc 时,它实际上为px_MyFrames 中的每个MY_FRAME 实例分配了3008 个字节的空间。这足以容纳uc_Framex_FrameHeader。因此,您不需要自己分配uc_Framemalloc 记得它已经分配了 3008 字节的空间,所以当你 free 它时,所有东西都会被释放。

【讨论】:

    【解决方案3】:

    它将被成​​功释放。您分配的内存空间的大小为sizeof(MY_FRAME)sizeof(MY_FRAME) 包含您的数组的大小,它将是sizeof(MY_FRAME_HEADER) + sizeof(unsigned char) * 3000。所以在释放它的时候,内存范围[px_MyFrames, px_MyFrames + sizeof(MY_FRAME))就会被释放。

    另外,另一种常见的方法是在结构中保存数组的指针,如下所示:

    typedef struct my_frame {
        MY_FRAME_HEADER x_FrameHeader;
        unsigned char  *uc_Frame;
    } MY_FRAME;
    

    而这一次的初始化和终结将是:

    /* initialization */
    px_MyFrames = (MY_FRAME *)malloc(sizeof(MY_FRAME) * MAX_NUMBER_OF_FRAMES);
    /* and the following line matters */
    px_MyFrames->uf_Frame = malloc(sizeof(ungisned char) * 3000);
    
    /* when in finalization */
    free(px_MyFrames->uf_Frame);
    free(px_MyFrames);
    

    顺便说一句,C 程序在正常返回时应返回0

    【讨论】:

    • 是的,抱歉,这只是一个快速编写的示例,但你是对的,它应该返回 0。
    • 是的,这就是我对第二个选项的意思,只是我需要一个 for 循环来为每个 uc_Frame 分配内存,而不仅仅是像你这样的第一个,如果我要使用所有 MAX_NUMBER_OF_FRAMES。释放每个 uc_Frame 也是如此。
    • @J.C.就个人而言,我不喜欢任何一种结构声明形式,尽管两者都可以。这取决于要存储的具体数据和使用情况。
    • @Pangyu CHEN 你会如何声明它们?我有一个帧(以太网、光纤通道等),它有一个标头部分,其中包含一些关于目标、源、长度、协议等的信息。然后我有实际的有效负载数据,它可能高达 3000 字节。在我看来,这是我能拥有的最简单的形式,但如果有更好的方法,我想知道为将来的项目学习它。
    • @J.C.它看起来和我在上面的答案中写的一样,其中结构包含一个指向动态分配的内存区域的指针。我正在使用这种样式来实现可调整大小的数组,以在某些项目中模拟 c++ 中的 std::vector。
    【解决方案4】:

    不关心uc_Frame 属性。您确实为MAX_NUMBER_OF_FRAMES * sizeof(MY_FRAME) 正确分配了内存,并且您可以正常使用和释放它。

    【讨论】:

      【解决方案5】:

      是的,所有内存都将被释放。 malloc 返回的区域将大到足以存储 10 个struct my_frames 的全部内容。当您调用free 时,它将释放整个区域。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-02-02
        • 2018-09-24
        • 1970-01-01
        • 1970-01-01
        • 2014-04-21
        • 2021-05-29
        相关资源
        最近更新 更多