Qubc
@Qubc
Ненавижу полисемию.

Сколько ячеек памяти будет занято при инициализации указателя адресом литерала?

Верно ли я понимаю, что:
char array [ ] = "Hello"; // будет занято 6 ячеек размера char, например с AABBCC00 по AABBCC06 ?
char * pointer = "Hello"; //будет занято 1+6 ячеек размера char, например с AABBCC00 по AABBCC06 и ячейка для указателя AABBCCFF?
  • Вопрос задан
  • 472 просмотра
Пригласить эксперта
Ответы на вопрос 5
@Korben5E
Любые указатели, в рамках одного приложения, имеют одинаковый размер, они просто содержат адрес данных - указывают на данные.

А строка на которую указывает - 6 знаков, 5 + \0 в конце.
Ответ написан
Комментировать
bingo347
@bingo347
Crazy on performance...
Во-первых, 1 ячейка памяти всегда имеет 1 фиксированный размер - машинное слово (на 64 битной архитектуре это будет 8 байт).
Во-вторых, компилятор си достаточно умный, что бы понимать, что сложные структуры данных вроде массивов и структур могут хранить все свои данные в 1 ячейке памяти, хотя могут и состоять из элементов меньше машинного слова. Но при этом данные относящиеся к разным структурам будут записаны в разные ячейки, даже если где-то окажется пустота.
В-третьих, массивы в си всего лишь сахар над указателями и арифметикой над указателями.
В-четвертых, не забываем, что сам указатель занимает машинное слово.

Отсюда делаем вывод, что оба представленных выражения полностью идентичны и оба займут 2 ячейки памяти, так как char занимает 1 байт, а массив из 6 char (5 букв и \0 символ) вполне влазит в 1 машинное слово, а указатель всегда имеет размер машинного слова. Вот если бы в строке было 8 символов (и последний не \0 символ), то понадобилось бы уже 3 ячейки памяти.
Ответ написан
wisgest
@wisgest
Не ИТ-специалист
Что мешает проверить:
printf("%d", sizeof pointer);
или
printf("%d", sizeof (char *));
или, поскольку размер указателя не зависит от типа,
printf("%d", sizeof (void *));
Ответ будет зависеть от архитектуры компьютера, модели памяти…
Ответ написан
Комментировать
CityCat4
@CityCat4
Внимание! Изменился адрес почты!
Нет, неверно.

В обеих случаях будет занято 10 байт (если предположить, что размер слова 4 байта). 6 байт займет строка "Hello\0" (zero-stop-byte будет добавлен автоматически) и 4 байта - указатель на нее. Просто в первом случае указателем будет &array[0].
Обычно явное указание массива требуется только в том случае, если планируются операции типа инкремента/декремента, в особенности по структурному типу или по указателям (массивы структур или указателей) - там можно переложить на компилер множество тупой работы по расчету смещений. Но вообще адресная арифметика в С - она как нож - в умелых руках творит чудеса, в неумелых - оборачивается серьезными травмами :D
Ответ написан
Комментировать
@res2001
Developer, ex-admin
Если оба объявления внутри функции, то:
  • В случае массива на стеке будет выделена память только под данные, т.е. 6 байт. Возможно, строка продублируется в сегменте данных и компилятор вставит операцию копирования данных из сегмента данных на стек при инициализации переменной. Пишу возможно, потому что я не проверял факт дублирования строки, но считаю, что скорее всего это именно так и работает. Таким образом памяти будет выделено 12 байт: 6 байт на стеке и 6 байт в сегменте данных.
  • В случае указателя, будет выделена память под сам указатель размером в sizeof(void*) байт на стеке, данные будут лежать в сегменте данных, указатель будет инициализирован адресом строки в сегменте данных.

Для обоих вариантов память в сегменте данных выделяется при старте программы загрузчиком ОС и освобождается только после завершения программы.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы