我有一个类似这样的结构:
struct rtok {
char type;
std::string val;
bool term;
};我正在编写一个简单的解释器,这个"rtok“结构就是我表示令牌的方式。我有一个"rtoks“向量,我遍历它生成解析树。
我的质询是,如果我的架构内有3位议员,而我只给予1位议员一个价值,其他议员会否仍记忆犹新呢?
我的意思是,如果我将"val“设置为"test”,我的令牌会只占4个字节还是占用6个字节?( "val“为4个字节,类型为1个字节,术语为1个字节)。
发布于 2015-02-15 13:36:10
假设您没有其他成员或虚拟函数,您的结构将始终占用sizeof(char) + sizeof(string) + sizeof(bool) + possible padding。string部件为自己分配一块内存,并在销毁时释放这些内存。但是,从技术上讲,这个内存并不是分配给struct的内存的一部分。
因此,无论您给出(或忽略)成员的值,结构总是具有相同的大小。
发布于 2015-02-15 13:48:19
别担心,这比你想象的要多得多。
有两个因素:数据对齐和内部类型实现。首先,关于数据对齐:您的结构中的所有类型都是自然对齐的,这意味着char可以位于任何地址,但是void*可能需要对齐4或8,这取决于体系结构。
因此,如果我们猜到,std::string在内部只使用char*来保持x32上的布局:
struct rtok {
char type;
char* val; // here char * for simplicity
bool term;
};sizeof(rtok)运算符将给出12个字节,而不是6个字节,内存占用情况如下所示:
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字节或更多。这个数量不是您可以使用的,这个数量用于管理堆内部结构,唯一可用的数量可以只有一个字节。
如果将所有内容加在一起,您会发现,即使计划只使用两个字符加类型,所消耗的内存量也会大得多。
发布于 2015-02-15 13:49:36
如前所述,struct总是固定大小的.有几种方法可以克服这一限制:
char[1]的“未绑定”数组作为最后一个成员,并为堆中的struct本身分配内存。union为重叠成员节省一些空间。https://stackoverflow.com/questions/28526585
复制相似问题