Sunday, 21 June 2015

Struct Hack in C


“Struct Hack” technique is used to create variable length member in a structure
Example:
struct employee
{
int emp_id;
int  name_len;
char name[1];
};
In gcc, when we create an array of length 1, it is considered as array of incomplete type.This technique is known as “Stuct Hack”. When we create array of variable length inside structure, it must be (and only) last member of structure.
Let us see below memory allocation.
struct employee *e = malloc(sizeof(*e) + sizeof(char) * 128);
is equivalent to
struct employee
{
int emp_id;
int  name_len;
char name[128]; /* character array of size 128 */
};

When we allocate memory as given above, compiler will allocate memory to store “emp_id” and “name_len” plus contiguous memory to store “name”. When we use this technique, gcc guaranties that, “name” will get contiguous memory.
Now we can use “name” same as pointer. e.g.
e->emp_id       = 100;
e->name_len     = strlen("Geeks For Geeks");
strncpy(e->name, "Geeks For Geeks", e->name_len);
Why not use a pointer?

struct Foo
{
  // ..
  size_t size;
  // data = (int*)malloc(sizeof(int) * 10);
  int *data;
};
The advantage of using an array is that you don’t have to allocate the memory elsewhere and make the pointer point to that. Thus there is no extra memory management. Furthermore, accesses to the memory will hit the memory cache (much) more likely because dynamically allocated block is contiguous.
Advantage of contiguous memory:

For example, by using this technique, we can allocate and deallocate memory by using single malloc and free call (because memory is contagious). Other advantage of this is, suppose if we want to write data, we can write whole data by using single “write()” call. e.g.
write(fd, e, sizeof(*e) + name_len); /* write emp_id + name_len + name */
If we use character pointer, then we need 2 write calls to write data. e.g.
write(fd, e, sizeof(*e));               /* write emp_id + name_len */
write(fd, e->name, e->name_len);        /* write name */
Note: In C99, there is feature called “flexible array members”, which works same as “Struct Hack”

Flexible array member:

C99 has a new language feature called “flexible array member”. It’s quite similar to the struct hack except an empty bracket [].
struct Foo
{
  size_t size;
  int data[]; // FLA
};
Example:
struct mystruct {
        int len;
        char chararray[1];  // some compilers would allow [0] here
    };
    char *msg = "abcdefghi";
    int n = strlen (msg);
    struct mystruct *ptr = malloc(sizeof(struct mystruct) + n + 1);
    ptr->len = n;
    strcpy (ptr->chararray, msg);
}



1 comment: