Рубрики

Struct Hack

Каков будет размер следующей структуры?

struct employee

{

    int     emp_id;

    int     name_len;

    char    name[0];

};

4 + 4 + 0 = 8 байт.

А как насчет размера «name [0]». В gcc, когда мы создаем массив нулевой длины, он считается массивом неполного типа, поэтому gcc сообщает его размер как «0» байтов. Эта техника известна как «Stuct Hack». Когда мы создаем массив нулевой длины внутри структуры, он должен быть (и только) последним членом структуры. Вскоре мы увидим, как его использовать.
Техника «Struct Hack» используется для создания элемента переменной длины в структуре. В приведенной выше структуре длина строки «name» не является фиксированной, поэтому мы можем использовать «name» в качестве массива переменной длины.

Давайте посмотрим ниже распределение памяти.

struct employee *e = malloc(sizeof(*e) + sizeof(char) * 128); 

эквивалентно

struct employee

{

    int     emp_id;

    int     name_len;

    char    name[128]; / * массив символов размером 128 * /

};

И ниже выделение памяти

struct employee *e = malloc(sizeof(*e) + sizeof(char) * 1024); 

эквивалентно

struct employee

{

    int     emp_id;

    int     name_len;

    char    name[1024]; / * массив символов размером 1024 * /

};

Примечание: поскольку name — это символьный массив, в malloc вместо «sizeof (char) * 128» мы можем напрямую использовать «128». sizeof используется, чтобы избежать путаницы.

Теперь мы можем использовать «имя» так же, как указатель. например

e->emp_id 	= 100;
e->name_len	= strlen("Geeks For Geeks");
strncpy(e->name, "Geeks For Geeks", e->name_len);

Когда мы выделяем память, как указано выше, компилятор выделяет память для хранения «emp_id» и «name_len» плюс непрерывную память для хранения «name». Когда мы используем эту технику, gcc гарантирует, что «имя» получит непрерывную память.
Очевидно, есть и другие способы решения проблемы, один из которых заключается в том, что мы можем использовать символьный указатель. Но нет никакой гарантии, что символьный указатель получит непрерывную память, и мы можем воспользоваться этой непрерывной памятью. Например, используя эту технику, мы можем выделять и освобождать память, используя один malloc и свободный вызов (потому что память является заразной). Другим преимуществом этого является то, что если мы хотим записать данные, мы можем записать целые данные, используя один вызов write (). например

write(fd, e, sizeof(*e) + name_len); /* write emp_id + name_len + name */ 

Если мы используем символьный указатель, то нам нужно 2 вызова write для записи данных. например

write(fd, e, sizeof(*e)); 		/* write emp_id + name_len */
write(fd, e->name, e->name_len);	/* write name */

Примечание: в C99 есть функция, называемая «гибкие элементы массива», которая работает так же, как «Struct Hack»

Эта статья составлена Нарендрой Кангралкар . Пожалуйста, напишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по обсуждаемой выше теме.

Рекомендуемые посты:

Struct Hack

0.00 (0%) 0 votes