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
不同,尤其是当该结构非常简单时,即只有一个我们都想要分配的成员?为了清楚起见,请参见下面与 student
和 student2
结构对应的代码。
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. 的“成员”当结构非常简单时,整个结构的主要内容,如果未能解决你的问题,请参考以下文章