Может ли кто-нибудь объяснить мне, как распределяется размер в следующем случае?

Я запутался с распределением размера с помощью моего компилятора 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, потому что вы проверяете указатель sizeof, а не саму структуру. sizeof(*link) даст вам правильный результат.

Nick S 29.05.2019 12:11
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
62
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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.

0___________ 29.05.2019 12:26

Но все же он широко используется в качестве примера, если вы кодируете приложение win32 и используете LPSTR, вы используете typedef char * PSTR, * LPSTR, поскольку это делает ваш код более легким для чтения и более простым.

João Rodrigues JR 29.05.2019 12:37

Нет, это делает код очень трудным для чтения. Это очень плохая практика, и использование в win32 не доказывает, что это хорошо.

0___________ 29.05.2019 12:42

Тогда как бы вы сделали это на практике?

João Rodrigues JR 29.05.2019 12:49

просто чтобы не скрывать указатели

0___________ 29.05.2019 12:51
  1. sizeof возвращаемый размер в байтах
  2. int иметь 32 бита = 4 байта
  3. Любой указатель char*, struct any* имеет const sizeof в зависимости от структуры памяти, в вашем случае это 8.
  4. Из-за нехватки памяти ваш первый пример имеет sizeof = 16, подробнее здесь: https://en.wikipedia.org/wiki/Data_structure_alignment, вы можете добавить #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. не могли бы вы вкратце объяснить мне, пожалуйста.

selvabharathi s 29.05.2019 12:46

@selvabharathis Размеры структур дополняются кратным наиболее строгому выравниванию любого из элементов внутри них. Например, если структура содержит элемент, который нужно выровнять по 8-байтовой границе, то размер будет дополнен до кратного 8.

Tom Karzes 29.05.2019 12:51

@selvabharathis Одна из причин этого заключается в том, что он может поместить несколько копий структуры в массив и все они будут правильно выровнены. Элементы массива размещаются непосредственно рядом друг с другом, поэтому, если первый элемент массива выровнен по 8-байтовой границе, то его размер должен быть кратен 8, чтобы сохранить 8-байтовое выравнивание для следующего элемента массива.

Tom Karzes 29.05.2019 12:51

вау, я понял, спасибо @tom-karzes

selvabharathi s 29.05.2019 13:00

@selvabharathis Также обратите внимание, что если ваша структура содержит int, за которым следует указатель, ей потребуется добавить 4 байта заполнения между к двум элементам структуры, чтобы выровнять указатель. Таким образом, если структура размещена на 8-байтовой границе, указатель будет правильно выровнен. Таким образом, вы должны принять во внимание последовательность, а также.

Tom Karzes 29.05.2019 13:14

@selvabharathis Например, если структура содержит int, затем указатель, затем еще один int, вы можете подумать, что она должна иметь длину 16 байтов, но на самом деле она должна быть 24 байта: 4 для первого int, затем 4 байтов заполнения, затем 8 для указателя, затем 4 для второго int и, наконец, еще 4 байта заполнения для заполнения размера структуры в целом. Таким образом, вы получаете 4+4+8+4+4 = всего 24 байта. Если бы вместо этого указатель был в начале или в конце, а целые были бы смежными, то размер был бы только 16. Таким образом, порядок влияет на это.

Tom Karzes 29.05.2019 13:16

@selvabharathis Ответ, который был указан как дубликат, более подробно описывает это.

Tom Karzes 29.05.2019 13:18

Другие вопросы по теме