Calloc со структурой с указателями в C
Я знаю, что память запроса calloc должна использоваться, записывает 0 во все биты и затем возвращает указатель на нее.
Мой вопрос: если я использую calloc со структурой, содержащей указатели, будут ли эти указатели иметь значение NULL или мне нужно установить их на NULL?
struct a{
char * name;
void * p;
}* A;
Итак, в основном, имя и p указывают на NULL после того, как я использовал calloc со структурой a?
Спасибо!
Ответы
Ответ 1
Как-то вы получили много неправильных ответов. C не требует представления нулевых указателей для всех нулевых битов. Многие ошибочно полагают, что это так, поскольку целочисленное постоянное выражение со значением 0, преобразованное в указатель, становится нулевым указателем.
С учетом сказанного, во всех системах реального мира нулевые указатели являются нулевыми битами, а calloc
- вполне разумный способ получить нулевой указатель-инициализированный массив указателей в реальном мире.
Ответ 2
R. ответ хорошо, но я хотел бы добавить стандартные кавычки для поддержки этого и показать способ 0 инициализировать вашу структуру, которая делает, в факт, выходные указатели NULL.
От N1548 (проект C11)
7.22.3.2 Функция calloc выделяет пространство для массива объектов nmemb, каждый из которых имеет размер есть размер. Пробел инициализируется ко всем битам 0. [289]
Затем в сноске говорится (выделено мной):
Обратите внимание, что это не обязательно должно быть таким же, как, представление нулевой точки с плавающей запятой или константы нулевого указателя.
Хотя нулевой указатель обычно представляется как все 0 бит, это представление не гарантируется. Чтобы ответить на ваш вопрос напрямую, нет, вы не можете полагаться на указатели calloc()
'd struct to be 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.
Ответ 3
Да, они будут. Аналогично, если вы это сделаете:
static char * a[100];
все указатели в массиве будут NULL.
Ответ 4
Стандарт ISO C для calloc
требует, чтобы он инициализировал все до 0
. Это означает, что если вы в конечном итоге сохраняете память, выделенную calloc
в качестве указателей, она действительно будет содержать указатели NULL (0).