可能重复:
Why isn’t sizeof for a struct equal to the sum of sizeof of each member?
我无法理解为什么会这样:
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
char b;
int a;
} A;
typedef struct
{
char b;
} B;
int main() {
A object;
printf("sizeof char is: %d\n",sizeof(char));
printf("sizeof int is: %d\n",sizeof(int));
printf("==> the sizeof both are: %d\n",sizeof(int)+sizeof(char));
printf("and yet the sizeof struct A is: %d\n",sizeof(object));
printf("why?\n");
B secondObject;
printf("pay attention that the sizeof struct B is: %d which is equal to the "
"sizeof char\n",sizeof(secondObject));
return 0;
}
我想我在代码中解释了我的问题,不再需要解释了。除了我有另一个问题: 我知道在堆/静态堆/堆栈上有分配,但是这意味着分配位置是未知的,它怎么可能?
我在谈论这个例子:
typedef struct
{
char *_name;
int _id;
} Entry;
int main()
{
Entry ** vec = (Entry**) malloc(sizeof(Entry*)*2);
vec[0] = (Entry *) malloc(sizeof (Entry));
vec[0]->_name = (char*)malloc(6);
strcpy (vec[0]->_name, "name");
vec[0]->_id = 0;
return 0;
}
我知道: vec在堆栈上。 * vec在堆上。 * vec [0]在堆上。 vec [0] - &gt; id在堆上。
但是: vec [0] - &gt; _name未知 为什么?
答案 0 :(得分:1)
在结构的构件之间和结构的末端存在未指定量的填充。在C中,结构对象的大小大于或等于其成员大小的总和。
答案 1 :(得分:0)
编译器可以在结构中自由添加填充以确保数据类型正确对齐。例如,int
将与sizeof(int)
个字节对齐。所以我希望A
结构的大小为8
。编译器执行此操作,因为从未对齐的地址获取int
最好效率低下,并且最坏的情况根本不起作用 - 这取决于计算机使用的处理器。对于大多数数据类型,x86将从未对齐的地址中快速获取,但是对于获取操作,将花费大约两倍的时间。
在您的第二个代码段中,您尚未声明i
。
所以vec[0]->_name
并不是未知的 - 它就在堆上,就像你从“malloc”(以及malloc
的兄弟姐妹)得到的任何东西一样。
答案 2 :(得分:0)
如果您搜索CPU和内存对齐,请查看this question以及this one和其他许多其他内容。简而言之,如果CPU访问与它们正在读取的数据大小一致的内存,则CPU会更快乐。例如,如果您正在读取uint16_t
,那么如果您读取的地址是2的倍数,则会更有效(在大多数CPU上)。为什么CPU以这种方式设计的细节是整个其他故事。
这就是为什么编译器会以额外的存储空间为代价,以最方便CPU访问它们的方式来解决并填充结构的字段。在您的情况下,假设char
为4个字节,您的int
和int
之间可能会有3个字节的填充。
如果你看一下C标准(我现在没有附近)或the man page of malloc,你会看到这样一句话:
malloc()和calloc()函数返回指向已分配内存的指针 适用于任何类型的变量。
这种行为正是由于我上面提到的相同原因。简而言之,内存对齐需要关注,这就是编译器在结构布局和其他地方为您做的事情,例如局部变量的布局等。
答案 3 :(得分:0)
你在这里遇到了结构填充。编译器插入可能在b
中的struct A
字段后插入三个字节的填充值,以便a
字段是4字节对齐的。您可以使用特定于编译器的位在某种程度上控制此填充;例如,在MSVC上,GCC上的pack pragma或aligned
属性,但我不建议这样做。结构填充用于指定成员对齐限制,并且某些体系结构将在未对齐访问时出错。 (其他人可能会手动修复对齐,但通常会执行此操作rather slowly。)
另请参阅:http://en.wikipedia.org/wiki/Data_structure_alignment#Data_structure_padding
关于你的第二个问题,我不确定你的名字是什么意思是“未知”。注意详细说明?