Если у меня есть структура А, определенный как:размер структуры массива
struct A {
char* c;
float f;
int i;
};
и массив
A col[5];
тогда почему
sizeof(*(col+0))
16?
Если у меня есть структура А, определенный как:размер структуры массива
struct A {
char* c;
float f;
int i;
};
и массив
A col[5];
тогда почему
sizeof(*(col+0))
16?
На вашей платформе для хранения этой структуры требуется 16 байт, причем структура имеет тип A
.
Вы должны иметь в виду, что *(col+0)
идентичен col[0]
так, что это только один структуры, а не весь массив из них. Если вы хотите размер массива, вы должны использовать sizeof(col)
.
Какая структура? «A» или «A [5]»? Ваш ответ не объясняет, почему sizeof не является чем-то вроде 80. –
Я ответил на вопрос, который был задан. В вашем ответе вы найдете много предположений о том, почему был задан вопрос, и я не вижу ничего в этом вопросе, чтобы оправдать эти предположения. –
Он, вероятно, сделал бы это, если бы ОП спросил, почему это не что-то вроде 80. Дэвид ответил на вопрос точно и правильно, как его спрашивали. (В моем собственном ответе я потакал некоторым размышлениям о том, о чем фактически беспокоился ОП.) –
Ваша проблема в том, что ваша процессорная платформа использует 8-байтовое выравнивание по поплавкам. Таким образом, ваш char * будет принимать 4 (если вы используете 32-битную систему), поскольку это указатель, который является адресом. Ваш float займет 8, а ваш int займет еще 4, что составляет 16 байт.
Компиляторы часто делают определенные типы согласованными на определенных границах байтов, чтобы ускорить вычисления на используемой аппаратной платформе.
Например, если вы сделали:
struct x {
char y;
int z;
};
Ваша система будет (возможно) сказать размер х был 8, дополняя полукокс из к междунар внутри структуры.
Вы можете добавить псевдокомментарии (зависит от реализации), чтобы остановить это:
#pragma pack(1)
struct x {
char y;
int z;
};
#pragma pack(0)
который сделает размер этого равным 5.
У некоторых процессоров 8-битное выравнивание по поплавкам? Я этого не слышал (хотя я не говорю, что вы ошибаетесь). Я просто предположил, что указатель был членом 8 байтов. –
Я не эксперт, но меня учили до этого по какой-то причине 8-байтовое выравнивание используется для поплавков по соображениям производительности. Я бы не знал, каковы были эти причины, так что, возможно, мы можем найти ссылку где-то :) Но он может просто быть на 64-битном, что сделало бы вас определенно более правильным, чем я, - я определенно наклонил мой, предположив, что ему 32 года по какой-то причине (не знаю, почему оглядываясь). –
имеет смысл. Однако ваш ответ намного лучше моего. –
Возможно, потому что:
char*
занимает 8 байтов, а int
и float
- 4 байта,char*
занимает 4 байта, но ваш компилятор решил, что массив будет быстрее, если он упадет на 4 байта. Заполнение может контролироваться большинством компиляторов с помощью #pragma pack (push, 1) и #pragma pack (pop) соответственно.Если вы хотите быть уверены, вы можете использовать offsetof
(на GCC) или создать объект и исследовать адреса своих полей членов, чтобы проверить, какие поля есть на самом деле мягкий и сколько.
Редактировать: Кажется, есть две части этого вопроса. «Почему sizeof(A)
равно 16?» В целом, я вижу теперь, что это, вероятно, вопрос, который был предназначен. Вместо этого я отвечаю на вторую часть, то есть «Почему sizeof(*(col+0)) == sizeof(A)
?»
col
- это массив. col + 0
не имеет смысла для массивов, поэтому компилятор должен сначала преобразовать col
в указатель.Тогда col
фактически просто A*
. Добавление нуля к указателю ничего не меняет. Наконец, вы разыменование его с *
и остается простым A
размера 16.
Короче говоря, sizeof(A) == sizeof(*(col+0))
PS: я не рассматривал вопрос «Почему, что один элемент массива принимает до 16 байт? " Другие ответили так хорошо.
Я дам вам 1 для редактирования, Аарон и для страданий стропов и стрел :-) – paxdiablo
На современном процессоре x86-64 char*
составляет 8 байт, float
- 4 байта, int
- 4 байта. Таким образом, размеры членов, добавленных вместе, равно 16. Что еще вы ожидаете? Кто-то сказал вам, что указатель - 4 байта? Потому что это справедливо только для x86-32.
Во-первых, ваше первоначальное объявление было неправильным (это теперь исправлено в редактировании вопроса). A
- название типа; объявить массив с именем col
, вы хотите
A col[5];
не
col A[5];
sizeof(*(col+0))
такой же, как sizeof col[0]
, который является таким же, как sizeof (A)
.
Это 16, потому что это размер этой структуры, для используемого вами компилятора и системы (вы не упомянули, что это такое).
Я беру это из вопроса, что вы ожидали чего-то другого, но вы этого не говорили.
Компиляторы могут вставлять байты заполнения между членами или после последнего элемента, чтобы обеспечить правильное выравнивание каждого элемента. Я нахожу 16 байтов неудивительным размером для этой структуры в 64-битной системе - и в этом конкретном случае, вероятно, нет необходимости в дополнении.
И если вы не знали, sizeof
дает результат в байтах, где байт обычно (но не всегда) 8 бит.
+1. Хорошее резюме различных точек. –
См. Http://en.wikipedia.org/wiki/Data_structure_alignment – Mysticial
Что такое col должно быть? –
@ user695652: если вы используете MSVC, включите предупреждения до '/ WALL', и он точно скажет вам почему. –