Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

struct hack - zero sized array

#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?

like image 821
Electrix Avatar asked Oct 20 '15 21:10

Electrix


People also ask

What is struct hack in C?

“Struct Hack” technique is used to create variable length member in a structure. In the above structure, string length of “name” is not fixed, so we can use “name” as variable length array. Let us see below memory allocation. struct employee *e = malloc(sizeof(*e) + sizeof(char) * 128);

Can we declare array of size 0 in C?

Declaring zero-length arrays is allowed in GNU C as an extension.

Why do some structures end with an array of size 1?

Some Windows structures are variable-sized, beginning with a fixed header, followed by a variable-sized array. When these structures are declared, they often declare an array of size 1 where the variable-sized array should be.


1 Answers

Yes, it's about padding/alignment. If you add __attribute__((__packed__)) to the end [useful when writing device drivers], you'll get 3 0 3 for your output.

If node1 had defined c[1], the size is 8 not 7, because the compiler will align c to an int boundary. With packed, sizeof would be 7

like image 170
Craig Estey Avatar answered Oct 21 '22 16:10

Craig Estey