Я запутался с распределением размера с помощью моего компилятора gcc, может ли кто-нибудь помочь мне, как размер распределяется для следующего кода.
struct node
{
int data;
struct node *next;
};
sizeof(struct node)
на выходе получается 16.
struct node
{
int data;
};
sizeof(struct node)
выдает результат 4.
struct node
{
struct node *next;
};
sizeof(struct node)
на выходе получается 8.
struct node
{
int data;
struct node *next;
}*link;
sizeof(link)
всегда 8, даже если я добавлю в структуру еще несколько элементов.
sizeof(link)
всегда будет возвращать 8 байтов, потому что это размер указателя на 64-битном компьютере.
Если вам нужен размер структуры, вам нужно сделать sizeof(struct node)
, так как это даст вам размер фактической структуры.
И для структуры типа связанного списка я бы рекомендовал вам что-то вроде этого
typedef struct node Node, *pnode;
struct node{
//some vars
pnode next;
}
Затем вам просто нужно объявить его своим основным или где угодно, как
pnode list = NULL;
sizeof(Node) //for memory allocation
ужасная привычка прятать указатели в typedefs.
Но все же он широко используется в качестве примера, если вы кодируете приложение win32 и используете LPSTR, вы используете typedef char * PSTR, * LPSTR, поскольку это делает ваш код более легким для чтения и более простым.
Нет, это делает код очень трудным для чтения. Это очень плохая практика, и использование в win32 не доказывает, что это хорошо.
Тогда как бы вы сделали это на практике?
просто чтобы не скрывать указатели
sizeof
возвращаемый размер в байтахint
иметь 32 бита = 4 байтаchar*
, struct any*
имеет const sizeof в зависимости от структуры памяти, в вашем случае это 8.#pragma pack(1)
и увидеть различия, должно быть 4 + 8 = 12На вашем конкретная платформа похоже, что int
имеет размер 4, а указатель имеет размер 8. Также похоже, что он хочет выровнять указатели по 8-байтовой границе.
Итак, если struct node
содержит только int
, то его размер равен 4. Если он содержит только указатель, его размер равен 8. Если он содержит и int
, и указатель, то ему требуется 12 байт, но для сохранения выравнивания указателя, он дополняет структуру до числа, кратного 8, в результате чего получается размер 16.
В вашем последнем примере вы определили link
как указатель на struct node
. В этом случае не имеет значения, что содержит struct node
. Поскольку link
— это просто указатель, его размер всегда будет равен 8.
Опять же, обратите внимание, что это всего лишь лучшее предположение для платформы твой. Ничто из этого не гарантируется и может варьироваться от одной платформы к другой.
спасибо, я получил четкое представление о вашем ответе, но я ударил в то место, где вы сказали, что структура дополняется до числа, кратного 8. не могли бы вы вкратце объяснить мне, пожалуйста.
@selvabharathis Размеры структур дополняются кратным наиболее строгому выравниванию любого из элементов внутри них. Например, если структура содержит элемент, который нужно выровнять по 8-байтовой границе, то размер будет дополнен до кратного 8.
@selvabharathis Одна из причин этого заключается в том, что он может поместить несколько копий структуры в массив и все они будут правильно выровнены. Элементы массива размещаются непосредственно рядом друг с другом, поэтому, если первый элемент массива выровнен по 8-байтовой границе, то его размер должен быть кратен 8, чтобы сохранить 8-байтовое выравнивание для следующего элемента массива.
вау, я понял, спасибо @tom-karzes
@selvabharathis Также обратите внимание, что если ваша структура содержит int
, за которым следует указатель, ей потребуется добавить 4 байта заполнения между к двум элементам структуры, чтобы выровнять указатель. Таким образом, если структура размещена на 8-байтовой границе, указатель будет правильно выровнен. Таким образом, вы должны принять во внимание последовательность, а также.
@selvabharathis Например, если структура содержит int
, затем указатель, затем еще один int
, вы можете подумать, что она должна иметь длину 16 байтов, но на самом деле она должна быть 24 байта: 4 для первого int
, затем 4 байтов заполнения, затем 8 для указателя, затем 4 для второго int
и, наконец, еще 4 байта заполнения для заполнения размера структуры в целом. Таким образом, вы получаете 4+4+8+4+4 = всего 24 байта. Если бы вместо этого указатель был в начале или в конце, а целые были бы смежными, то размер был бы только 16. Таким образом, порядок влияет на это.
@selvabharathis Ответ, который был указан как дубликат, более подробно описывает это.
читайте о заполнении и выравнивании структуры, sizeof(link) равен 8, потому что вы проверяете указатель sizeof, а не саму структуру. sizeof(*link) даст вам правильный результат.