struct hack - 零大小的数组 [英] struct hack - zero sized array
问题描述
#include< iostream>
使用namespace std;
struct node1 {
char b [3];
int c [0];
};
struct node2 {
int c [0];
};
struct node3 {
char b [3];
};
int main(){
cout<< sizeof(node1)<< ENDL; //打印4
cout<< sizeof(node2)<< ENDL; //打印0
cout<< sizeof(node3)<< ENDL; //打印3
}
我的问题是为什么编译器为int分配0字节节点2
中的c [0],但当node1的一部分时为其分配1个字节。
我假设这个1字节是sizeof(node1)返回4的原因,因为没有它(像在node3中)它的大小是3或者是由于填充?
还试图理解node2是否应该有足够的空间来容纳一个指向数组的指针(它将作为灵活的数组/结构hack的一部分在代码中进一步分配) p>
是的,padding有所不同。 node1
字节,而 node3
不包含在零长度数组中。
零长度数组通常与cast一起使用:您将一个较大的(可能是可变大小的)对象转换为包含零长度数组的结构,然后使用零长度数组访问大对象的休息,其中这个目的必须正确对齐,填充字节插在零大小的数组之前,这样 int
s是对齐的,Sin您不能使用 node3
来做到这一点,不需要填充。
示例:
struct消息{
char类型[3];
int Data []; //编译时不显式加$ 0
};
void ReceiveMessage(unsigned char * buffer,size_t length){
if(length< sizeof(Message))
return;
Message * msg =(Message *)buffer;
if(!memcmp(msg-> Type,GET,3)){
HandleGet(msg-> Data,(length - sizeof(Message))/ sizeof(int));
}否则如果......
注意:这样做很冒险,但效率很高。
#include <iostream>
using namespace std;
struct node1{
char b[3];
int c[0];
};
struct node2{
int c[0];
};
struct node3{
char b[3];
};
int main() {
cout << sizeof(node1) << endl; // prints 4
cout << sizeof(node2) << endl; // prints 0
cout << sizeof(node3) << endl; // prints 3
}
My Question is why does the compiler allocate 0 bytes for int c[0] in node2 but allocate 1 byte for its when part of node1. I'm assuming that this 1 byte is the reason why sizeof(node1) returns 4 since without it (like in node3) its size is 3 or is that due to padding??
Also trying to understand that shouldn't node2 have enough space to hold a pointer to an array (which will be allocated in the further down in the code as part of the flexible array/struct hack?
Yes, padding makes the difference. The reason why node1
has a padding byte, while node3
doesn't, lies in the typical usage of zero-length arrays.
Zero-length arrays are typically used with casting: You cast a larger, (possibly variable-sized) object to the struct containing the zero-length array. Then you access the "rest" of the large object using the zero-length array, which, for this purpose, has to be aligned properly. The padding byte is inserted before the zero-sized array, such that the int
s are aligned. Since you can't do that with node3
, no padding is needed.
Example:
struct Message {
char Type[3];
int Data[]; // it compiles without putting 0 explicitly
};
void ReceiveMessage(unsigned char* buffer, size_t length) {
if(length < sizeof(Message))
return;
Message* msg = (Message*)buffer;
if(!memcmp(msg->Type, "GET", 3)) {
HandleGet(msg->Data, (length - sizeof(Message))/sizeof(int));
} else if....
Note: this is rather hackish, but efficient.
这篇关于struct hack - 零大小的数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!