Calloc со структурой с указателями в C - PullRequest
12 голосов
/ 02 мая 2011

Я знаю, что используемая память запроса calloc записывает 0 во все биты и затем возвращает указатель на нее.

У меня такой вопрос: если я использую calloc со структурой, содержащей указатели, будут ли эти указатели иметь значение NULL или я должен установить для них значение NULL?

struct a{
char * name;
void * p;
}* A;

Итак, в основном, имя и p будут указывать на NULL после того, как я использовал calloc со структурой a?

Спасибо!

Ответы [ 4 ]

23 голосов
/ 02 мая 2011

Как-то вы получили много неправильных ответов. C не требует, чтобы представление нулевых указателей было полностью нулевым. Многие ошибочно полагают, что это так, поскольку целочисленное константное выражение со значением 0, преобразованное в указатель, становится нулевым указателем.

С учетом сказанного, во всех реальных системах нулевые указатели являются полностью нулевыми битами, и calloc является совершенно разумным способом получить инициализированный нулевым указателем массив указателей в реальном мире.

16 голосов
/ 09 августа 2014
Ответ

R. хороший, но я бы хотел добавить стандартные кавычки для поддержки этого и показать способ инициализации структуры 0, который фактически дает указатели NULL.

С N1548 (черновик C11)

7.22.3.2 Функция calloc выделяет пространство для массива объектов nmemb, каждый изчей размер есть размер.Пробел инициализируется всеми битами, равными нулю. [289]

Сноска затем говорит (выделение добавлено):

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

Хотя нулевой указатель обычно представляется как все 0 битов, это представление не гарантируется.Чтобы ответить на ваш вопрос напрямую, no вы не можете полагаться на указатели calloc() 'struct, которые будут NULL.


Если вы хотите установить все содержащиеся в нем указателидинамически распределяемая структура для NULL вы можете использовать следующее:

struct a *s = malloc(sizeof *s);
*s = (struct a){0};

C11:

6.7.9.21 Если в фигурной скобке меньше инициализаторов-Закрытый список, в котором есть элементы или элементы агрегата, [...] остальная часть агрегата должна быть неявно инициализирована так же, как объекты, имеющие статическую длительность хранения

и

6.7.9.10 ... Если объект, имеющий статическую или потоковую длительность хранения, не инициализирован явно, то:- если он имеет тип указателя, он инициализируется нулевым указателем;

C требует, чтобы в скобках был хотя бы один элемент, поэтому я использую {0} вместо{}.Остальные элементы инициализируются в соответствии с приведенными выше правилами, что приводит к нулевым указателям.Насколько я могу судить, правила для этого одинаковы в C11 и C99.

0 голосов
/ 02 мая 2011

Стандарт ISO C для calloc требует, чтобы он инициализировал все до 0.Это означает, что если вы в конечном итоге увидите память, выделенную calloc в качестве указателей, она действительно будет изначально содержать NULL (0) указателей.

0 голосов
/ 02 мая 2011

Да, они будут. Аналогично, если вы сделаете это:

static char * a[100];

все указатели в массиве будут NULL.

...