malloc struct vs. 的“成员”当结构非常简单时,整个结构

Posted

技术标签:

【中文标题】malloc struct vs. 的“成员”当结构非常简单时,整个结构【英文标题】:malloc a "member" of struct v.s. whole struct when struct is quite simple 【发布时间】:2021-11-17 00:59:49 【问题描述】:

我在这个网站上搜索了关于结构的malloc 的主题。但是,我有一个小问题。结构元素上的malloc 是否与整个结构上的malloc 不同,尤其是当该结构非常简单时,即只有一个我们都想要分配的成员?为了清楚起见,请参见下面与 studentstudent2 结构对应的代码。

struct student 
    int* majorScore;
;

struct student2 
    int majorScore[3];
;


int main()

    struct student john;
    john.majorScore = (int*) malloc(sizeof(int) * 3);
    john.majorScore[0] = 50;
    john.majorScore[1] = 27;
    john.majorScore[2] = 56;
 
    struct student2* amy= (struct student2*)malloc(sizeof(struct student2));
    amy->majorScore[0] = 50;
    amy->majorScore[1] = 27;
    amy->majorScore[2] = 56;


    return 0;

它们的内存级别不同吗?如果是,有什么区别?如果不是,就良好的编程风格而言,哪个可能更好?

【问题讨论】:

malloc 在结构上只会分配结构本身的大小,而不是结构内指针指向的动态数据的大小。 你不是在比较喜欢和喜欢。对于john,您在本地struct 中分配数组。对于amy,您在具有固定数组的堆上分配一个struct。哪个更好?如果你不知道编译时有多少分数,它们就不可能有一个固定的数组。 它们的内存级别不同吗?好吧,您提供了两种不同的结构定义,因此在这方面它们是不同的。它们的相同之处在于动态分配的数据将存在于内存的.heap 部分中的某处。就良好的编程风格而言,哪个更好?有争议并取决于您的用例。我认为大小为 3 的 majorScore 数组对于实际场景来说是不现实的,但如果它符合您的需求,那么使用这种方法就可以了。 student2 包含一个由int 组成的三元素数组。 student 包含一个 int 指针。这是两个非常不同的东西。 不要投 malloc() 【参考方案1】:

首先,您动态分配一个结构,而不是另一个。所以你是在比较苹果和橙子。


静态分配的结构:

struct student john;
john.majorScore = malloc(sizeof(int) * 3);
john.majorScore[0] = 50;
john.majorScore[1] = 27;
john.majorScore[2] = 56;

struct student2 amy;
amy.majorScore[0] = 50;
amy.majorScore[1] = 27;
amy.majorScore[2] = 56;
struct student john
+------------+----------+      +----------+
| majorScore |         ------->|       50 |
+------------+----------+      +----------+
| [padding]  |          |      |       27 |
+------------+----------+      +----------+
                               |       56 |
                               +----------+

struct student2 amy
+------------+----------+
| majorScore |       50 |
|            +----------+
|            |       27 |
|            +----------+
|            |       56 |
+------------+----------+
| [padding]  |          |
+------------+----------+

struct student 使用更多内存,因为它有一个额外的值(指针),而且它的开销是两个内存块而不是一个。

struct student2 总是有正好三个分数的内存,即使你需要更少的分数。而且它不可能容纳超过 3 个。


动态分配的结构:

struct student *john = malloc(sizeof(struct student));
john->majorScore = malloc(sizeof(int) * 3);
john->majorScore[0] = 50;
john->majorScore[1] = 27;
john->majorScore[2] = 56;

struct student2 *amy = malloc(sizeof(struct student2));
amy->majorScore[0] = 50;
amy->majorScore[1] = 27;
amy->majorScore[2] = 56;
struct student *john
+----------+      +------------+----------+      +----------+
|         ------->| majorScore |         ------->|       50 |
+----------+      +------------+----------+      +----------+
                  | [padding]  |          |      |       27 |
                  +------------+----------+      +----------+
                                                 |       56 |
                                                 +----------+

struct student2 *amy
+----------+      +------------+----------+
|         ------->| majorScore |       50 |
+----------+      |            +----------+
                  |            |       27 |
                  |            +----------+
                  |            |       56 |
                  +------------+----------+
                  | [padding]  |          |
                  +------------+----------+

分析如上。

【讨论】:

用于说明数据存储的精彩图表 不要忘记malloc() 的实现在返回的指针之前添加了大量的数据。此外,通常分配的最小块是 32 字节。 非常感谢大家。很难选择最佳接受的答案,您的和 h0r53 的答案非常有帮助。【参考方案2】:

结构上的 malloc 简单吗?当然,它确实是。尽管您的struct student2 定义不需要任何malloc,但我认为直接使用结构并避免malloc 要简单得多。需要注意的是,结构上的malloc 只会分配结构本身的大小,而不是结构内指针指向的动态数据的大小。您要比较的是两个不同的结构,它们的实现非常不同,因此说“哪个更好”并不公平,因为这在很大程度上取决于您的实际用例。

为了清楚起见,假设你做了struct student* john = malloc(sizeof(struct student))。如果你为这样的结构分配存储空间,你仍然需要为majorScore 分配内存,因为它最初的malloc 只为int * 分配空间,除此之外什么都没有。如您所见,这使事情变得更加复杂。

所以结论是,一般来说,在编译时可能不知道数据大小的情况下,您只想使用malloc 进行动态内存分配。在您提供的示例中,没有理由通过 malloc 引入复杂性(以及可能的错误/泄漏)。在struct student 的示例中使用malloc 的效用是majorScore 可以是任意大小的数组,而不仅仅是struct student2 定义中的3。

【讨论】:

我明白了!非常感谢!

以上是关于malloc struct vs. 的“成员”当结构非常简单时,整个结构的主要内容,如果未能解决你的问题,请参考以下文章

使用 stl map 作为 struct 的成员

在c中struct的成员中间调用free时会发生什么?

struct 内部的 malloc 结构数组

Malloc和Struct

C Struct typdef malloc 赋值

与struct和malloc共享内存fork