首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++结构成员内存分配

C++结构成员内存分配
EN

Stack Overflow用户
提问于 2015-02-15 13:31:39
回答 3查看 3.8K关注 0票数 1

我有一个类似这样的结构:

代码语言:javascript
复制
struct rtok {
    char type;
    std::string val;
    bool term;
};

我正在编写一个简单的解释器,这个"rtok“结构就是我表示令牌的方式。我有一个"rtoks“向量,我遍历它生成解析树。

我的质询是,如果我的架构内有3位议员,而我只给予1位议员一个价值,其他议员会否仍记忆犹新呢?

我的意思是,如果我将"val“设置为"test”,我的令牌会只占4个字节还是占用6个字节?( "val“为4个字节,类型为1个字节,术语为1个字节)。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-02-15 13:36:10

假设您没有其他成员或虚拟函数,您的结构将始终占用sizeof(char) + sizeof(string) + sizeof(bool) + possible paddingstring部件为自己分配一块内存,并在销毁时释放这些内存。但是,从技术上讲,这个内存并不是分配给struct的内存的一部分。

因此,无论您给出(或忽略)成员的值,结构总是具有相同的大小。

票数 5
EN

Stack Overflow用户

发布于 2015-02-15 13:48:19

别担心,这比你想象的要多得多。

有两个因素:数据对齐和内部类型实现。首先,关于数据对齐:您的结构中的所有类型都是自然对齐的,这意味着char可以位于任何地址,但是void*可能需要对齐4或8,这取决于体系结构。

因此,如果我们猜到,std::string在内部只使用char*来保持x32上的布局:

代码语言:javascript
复制
struct rtok {
  char type;
  char* val; // here char * for simplicity
  bool term;
};

sizeof(rtok)运算符将给出12个字节,而不是6个字节,内存占用情况如下所示:

代码语言:javascript
复制
00: type (one byte)
01: padding
02: padding
03: padding
04-07: char * (4 bytes)
08: term (one byte)
09-0a: padding (3 bytes)

现在,如果我们用char*替换std::string,我们会发现结构的大小已经增长了,因为sizeof(std::string)通常比4个字节大。

但是,我们还没有计算字符串值本身。在这里,我们进入了堆管理和分配领域。

用于存储值的内存是在堆上分配的,而代码通常请求的量随需要而定,因此对于10个字符的字符串,它将是11个字节(10个字符加上null终止符的1个字节)。

而堆本身具有复杂的结构,具有小块堆等。在实际应用中,它意味着最小消耗量约为16字节或更多。这个数量不是您可以使用的,这个数量用于管理堆内部结构,唯一可用的数量可以只有一个字节。

如果将所有内容加在一起,您会发现,即使计划只使用两个字符加类型,所消耗的内存量也会大得多。

票数 2
EN

Stack Overflow用户

发布于 2015-02-15 13:49:36

如前所述,struct总是固定大小的.有几种方法可以克服这一限制:

  1. 存储指针并为其分配堆内存。
  2. 使用char[1]的“未绑定”数组作为最后一个成员,并为堆中的struct本身分配内存。
  3. 使用union为重叠成员节省一些空间。
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28526585

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档