Как массив размером 0 хранится в памяти? - PullRequest
0 голосов
/ 29 августа 2018

Если у меня есть массив только из одного элемента, мы можем сказать, что он совпадает с указателем. Но как массив нулевого размера представлен в памяти?

Что происходит, когда я объявляю переменную int * table[0]?

Ответы [ 3 ]

0 голосов
/ 29 августа 2018

Если у меня есть массив только из одного элемента, мы можем сказать, что он такой же, как указатель

Нет, мы не можем. Массивы и указатели являются разными типами, и они представлены по-разному внутри. Это верно независимо от размера массива. Теперь также верно, что в определенных ситуациях (в большинстве случаев на самом деле) массив распадается на указатель на свой первый элемент.

Массивы размером 0 недопустимы в соответствии со стандартом, однако некоторые крупные компиляторы, такие как gcc, допускают их как расширение.

Прочтите этот вопрос, чтобы увидеть разницу между внутренними представлениями массивов и указателей: Разница между разыменованием указателя и доступом к элементам массива

0 голосов
/ 29 августа 2018

Строго говоря, массив не может иметь размер 0. Это продиктовано в разделе 6.7.6.2p1 стандарта C :

В дополнение к необязательным квалификаторам типов и ключевому слову static, [ и] может разделять выражение или * Если они разграничивают выражение (которое определяет размер массива), выражение должно иметь целочисленный тип. Если выражение является константным выражением, оно должно иметь значение больше нуля. Тип элемента не должен быть неполным или функциональным. необязательные квалификаторы типов и ключевое слово static должны появиться только в объявлении параметра функции с массивом тип, а затем только в самом внешнем типе массива

Некоторые компиляторы поддерживают это как расширение, например GCC :

Объявление массивов нулевой длины разрешено в GNU C как расширение. массив нулевой длины может быть полезен в качестве последнего элемента структуры это действительно заголовок для объекта переменной длины:

struct line {
  int length;
  char contents[0];
};

struct line *thisline = (struct line *)
  malloc (sizeof (struct line) + this_length);
thisline->length = this_length;

Хотя размер массива нулевой длины равен нулю, член массива этот вид может увеличить размер охватывающего типа в результате обивка хвоста. Смещение элемента массива нулевой длины из начало ограждающей конструкции совпадает со смещением массив с одним или несколькими элементами одного типа. Выравнивание массив нулевой длины совпадает с выравниванием его элементов.

0 голосов
/ 29 августа 2018

Массивы нулевой длины технически не поддерживаются стандартом C. Однако некоторые компиляторы, такие как gcc, допускают их как расширение.

Это способ создания гибких элементов массива до C99, как показано здесь:

typedef struct {
    int len;
    int contents[0];
} arr;

Затем вы можете инициализировать столько места, сколько захотите для массива в конце:

arr* a = malloc(sizeof(*a) + sizeof(a->contents) * 10); /* for a length-10 array */
a->len = 10;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...