Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 23.10.2011, 17:14   #1
LockHeart
Пользователь
 
Регистрация: 23.10.2011
Сообщений: 14
По умолчанию Массив

c++
Хотелось бы поподробнее узнать про простую конструкцию:

char array[] = "word";

Известно, что само слово "word" будет в неизменном виде храниться в сегменте данных. Раньше думал, что сам "array" будет храниться в стеке и содержать указатель на участок сегмента данных, в котором расположен "word", однако, оказалось, это не совсем так...) Хотелось бы достучаться до истины...

LockHeart вне форума Ответить с цитированием
Старый 23.10.2011, 17:34   #2
Сыроежка
Форумчанин
 
Регистрация: 01.07.2011
Сообщений: 423
По умолчанию

Цитата:
Сообщение от LockHeart Посмотреть сообщение
c++
Хотелось бы поподробнее узнать про простую конструкцию:

char array[] = "word";

Известно, что само слово "word" будет в неизменном виде храниться в сегменте данных. Раньше думал, что сам "array" будет храниться в стеке и содержать указатель на участок сегмента данных, в котором расположен "word", однако, оказалось, это не совсем так...) Хотелось бы достучаться до истины...

Вы наверное раньше путали два объявления

Код:
char array[] = "word";
и

Код:
const char *s = "word";
В первом случае создается массив с именем array, который инициализируется символами строкового литерала "word", включая дополнительный символ завершающего нуля. То есть данный массив будет иметь размерность, равную 5. Причем совсем не обязательно, что этот массив будет создаваться в стеке. Он может быть создан и в статической области памяти, если будет объявлен в глобальном пространстве имен, то есть вне любой функции, либо если будет объявлен со спецификатором памяти static внутри какой-нибудь функции.
Важно так же отметить, что в данном примере сам строковый литерал "word" в памяти не хранится, а используется лишь для инициализации массива. То есть это именно проинициализированный массив таким образом будет храниться в памяти.

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

Код:
const char *s1 = "word";
const char *s2 = "word";
то стандарт также не оговаривает, будет ли в памяти храниться один строковый литерал, так как данные литералы совпадают, или же два отдельных строковых литерала. Поэтому совсем не обязательно, что

Код:
( s1 == s2 ) == true;
В С++ строковый литерал имеет тип const char[],поэтому и указатели на них следует объявлять как const char *, Тем не менее стандарт позволяет указатели на строковые литералы объявлять без квалификатора const, как char *, в целях обеспечения совместимости со старым программным кодом.
Со мной можно встретиться на www.clipper.borda.ru
Сыроежка вне форума Ответить с цитированием
Старый 28.10.2011, 02:12   #3
LockHeart
Пользователь
 
Регистрация: 23.10.2011
Сообщений: 14
По умолчанию

В таком случае, если массив создан не глобальным и не константным, где он будет храниться и сколько памяти под него будет отведено?

Если "word" не хранится в памяти, то откуда он будет взят, чтобы проинициализировать массив?

Если я правильно понял логику, то сам массив будет храниться в стеке(опять же, сколько под него выделится места?), "word" будет находиться внутри .exe файла (там, насколько я понял, хранится только код и статические переменные). В момент компиляции слово "word" будет записано в этот массив, и впоследствии мы сможем дополнять массив, просто добавляя в него другие однотипные элементы-чары. Это близко к правде?
LockHeart вне форума Ответить с цитированием
Старый 28.10.2011, 10:23   #4
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию Надеюсь, что нигде не напутал

Цитата:
Сообщение от LockHeart Посмотреть сообщение
В таком случае, если массив создан не глобальным и не константным, где он будет храниться и сколько памяти под него будет отведено?

Если "word" не хранится в памяти, то откуда он будет взят, чтобы проинициализировать массив?

Если я правильно понял логику, то сам массив будет храниться в стеке(опять же, сколько под него выделится места?), "word" будет находиться внутри .exe файла (там, насколько я понял, хранится только код и статические переменные). В момент компиляции слово "word" будет записано в этот массив, и впоследствии мы сможем дополнять массив, просто добавляя в него другие однотипные элементы-чары. Это близко к правде?
ВЕСЬ код программы (в предположении, что мы не используем динамических библиотек), с данными и прочими рюшечками, находится в исполняемом файле. Также в этом файле хранится информация, какие части при загрузке программы в память размещать по каким адресам-сегментам.
При запуске файла на выполнение, код из файла загружается в оперативную память; тогда же, фактически, возникает понятие сегментов. То есть, в процессе выполнения программы про exe-файл можно вообще забыть (к слову, операционная система обычно не даёт программе модифицировать файл, из которого она была запущена).

Соответственно, если в исходном коде программы есть строковый литерал, он "переедет" в исполняемый файл, а затем и в оперативную память, как набор символов. Где именно в оперативной памяти он будет размещён - вообще говоря, забота компилятора, а не программиста.
Переменная, объявленная внутри функции без указания класса памяти, по умолчанию получает место в стеке: предоставленная ей область памяти неприкосновенна только до тех пор, пока мы не вышли из функции (поэтому категорически нельзя передавать из функции "наружу" адреса локальных не-статических переменных - это чревато весьма трудноуловимыми ошибками). Количество выделяемого места определяется типом переменной и предпочтениями компилятора по выравниванию (int и указатель получат на 32-разрядных системах 4 байта, а char может получить как 1 байт, так и все 4, 3 из которых не будут использоваться). Тип char[5] - это размер в пять байт, как минимум столько и будет выделено в стеке (при каждом обращении к нашей функции). C++ позволяет не писать размер массива, если его можно понять по контексту - как в данном случае, когда содержание массива есть литерал длины 5.
Abstraction вне форума Ответить с цитированием
Старый 30.10.2011, 23:42   #5
LockHeart
Пользователь
 
Регистрация: 23.10.2011
Сообщений: 14
По умолчанию

Большое спасибо)
LockHeart вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
С# задан массив 5х5. сформировать массивы А и В. в массив А поместить элементы с четными индексами, в массив В с нечетны Koksa Помощь студентам 0 10.10.2011 11:26
Запись координат в массив в реал тайм, Как записать координаты в массив Dark19 Visual C++ 2 21.06.2011 18:45
Из массив А получить массив В, удвоив все нечётные элементы удвоены ( на Pascal) KARTER Помощь студентам 1 18.06.2011 19:58
Массив - Нужно написать массив и распечатать на экран с конца в начало(язык С++) econ Помощь студентам 1 29.05.2011 22:02
Упорядочить массив в порядке возрастания и напечатать входной и исходный массив. TheVenny Помощь студентам 3 26.11.2008 15:06