Аннотация:
Рассмотрены вопросы организации памяти в С++, базовые принципы управления ею, основы работы с указателями. Представление рассматриваемых конструкций и понятий осуществляется с позиций их реализации, внутреннего устройства, что позволяет не только запомнить, как работает тот или иной оператор, та или иная конструкция, но и понять, почему они работают именно так.
Чтобы хорошо работать, надо получать от этого удовольствие! (c) Michael Schumacher
On 15.07.2011 12:05, Костарев Александр Николаевич wrote: > Размещение объектов в оперативной памяти. Понятие указателя. Часть 2. Арифметика > указателей, массивы <http://rsdn.ru/article/?1103>
On 15.07.2011 12:05, Костарев Александр Николаевич wrote:
> *Статья:* > Размещение объектов в оперативной памяти. Понятие указателя. Часть 2. Арифметика > указателей, массивы
Круто. Скоро у нас будут статьи типа
"Работа оператора if. Часть 5. else и его разновидности."
Здравствуйте, MasterZiv, Вы писали:
>> *Статья:* >> Размещение объектов в оперативной памяти. Понятие указателя. Часть 2. Арифметика >> указателей, массивы MZ>Круто. Скоро у нас будут статьи типа MZ>"Работа оператора if. Часть 5. else и его разновидности."
Статью не читал но одобряю. По крайней мере для C больше будет статей чем для немерле
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
"Массивы, равно как и любые другие виды объектов, могут быть размещены как в
стеке, так и в динамической памяти."
Ещё массивы можно просто в памяти размещать. В виде глобальных и статических
глобальных переменных. Ещё можно локальные статические переменные функций
делать.
"Код первой строки функции main выполняет такое размещение:"
Это объявление переменной и её инициализация. Никакого размещения там нет.
Замечания типа:
"
Ещё раз отметим, что объекты, составляющие массив, размещаются в памяти
непосредственно друг за другом — адрес каждого следующего объекта есть адрес
предыдущего, смещённый на размер объекта."
Потому как есть ли дырки между элементами массива -- науке неизвестно.
"Операция постфиксного инкремента имеет более высокий приоритет, чем операция
разыменования, следовательно, в выражении *p++ сначала к указателю p применяется
операция постфиксного инкремента, после чего к её результату (к значению,
возвращенному операцией постфиксного инкремента) применяется операция
разыменования."
-- тоже достаточно мутная формулировка. Надо было написать что
*p++
--
это
*(p++)
и о ПОРЯДКЕ не говорить ничего, либо что СНАЧАЛА выполнится разименование,
а ЗАТЕМ инкрементация указателя.
Здравствуйте, MasterZiv, Вы писали:
MZ>Замечания типа:
MZ>" MZ>Ещё раз отметим, что объекты, составляющие массив, размещаются в памяти MZ>непосредственно друг за другом — адрес каждого следующего объекта есть адрес MZ>предыдущего, смещённый на размер объекта."
MZ>Потому как есть ли дырки между элементами массива -- науке неизвестно.
Со структурами не путаете? Между элементами массива никаких дырок не может быть.
Здравствуйте, MasterZiv, Вы писали:
>> *Статья:* >> Размещение объектов в оперативной памяти. Понятие указателя. Часть 2. Арифметика >> указателей, массивы MZ>Круто. Скоро у нас будут статьи типа MZ>"Работа оператора if. Часть 5. else и его разновидности."
Статья для начинающих, что такого
Здравствуйте, breee breee, Вы писали:
BB>Здравствуйте, MasterZiv, Вы писали:
MZ>>Замечания типа:
MZ>>" MZ>>Ещё раз отметим, что объекты, составляющие массив, размещаются в памяти MZ>>непосредственно друг за другом — адрес каждого следующего объекта есть адрес MZ>>предыдущего, смещённый на размер объекта."
MZ>>Потому как есть ли дырки между элементами массива -- науке неизвестно.
BB>Со структурами не путаете? Между элементами массива никаких дырок не может быть.
могут быть изза выравнивания
(не по стандарту, но IRL такое возможно)
Здравствуйте, MasterZiv, Вы писали:
MZ>On 15.07.2011 12:05, Костарев Александр Николаевич wrote:
>> *Статья:* >> Размещение объектов в оперативной памяти. Понятие указателя. Часть 2. Арифметика >> указателей, массивы
MZ>Круто. Скоро у нас будут статьи типа MZ>"Работа оператора if. Часть 5. else и его разновидности."
для такой простой статьи — слишком много ошибок, неточностей, плохого кода
> cout << arr[0] << endl << arr[1] << endl << arr[2] << endl;
endl имеет сложную семантику, чтобы просто вставить символ перевода строки лучше использовать '\n'
> Массивы, равно как и любые другие виды объектов, могут быть размещены как в стеке, так и в динамической памяти.
и еще много где
> int arr[3] = {10, 20, };
в тексте не прокомментирована запятая в конце списка
> объекты, составляющие массив, размещаются в памяти непосредственно друг за другом — адрес каждого следующего объекта есть адрес предыдущего, смещённый на размер объекта. > количество элементов размещённого в стеке массива можно рассчитать по формуле sizeof(имя массива) / sizeof(тип элемента).
в реальной жизни это может быть не так. лучше использовать что-то вроде
sizeof(arr) / ((const char*)&arr[1] — (const char*)&arr[0])
или метафункцию (std::extent например)
> Наличие модификатора const в определении объекта n существенно. Без этого модификатора n становится переменной;
одного const не достаточно, надо чтобы n была константой времени компиляции.
> while(*p++ = *s++);
этот код не будет компилироваться если предупреждения компилятора трактуются как ошибки
> Строка (более точно, C-строка) — это массив символов (объектов типа char), завершающийся нулём (символом ‘\0’).
а еще более точно "Строка символов типа char с нулевым символом на конце — это ..."
L"..." тоже строка
ИМО, обучающие статьи не должны писаться так как будто "новичкам и такое объяснение сойдет"
BB>>Со структурами не путаете? Между элементами массива никаких дырок не может быть.
MZ>А если в массиве структуры ?
если в массиве структуры, то дырки (если они есть) есть в структуре (либо между членами, либо паддинг в конце) -- все эти дырки учитываются в размере sizeof структуры. А дырок между элементами массива нет в любом случае.
Здравствуйте, trophim, Вы писали: T>А как верно?
В языке C есть variable-length arrays — массивы переменного размера, которые обычно как-раз и размещаются на стеке.
Кроме того, массив на стеке можно явно создать вызовом функции alloca(), или, если нужно, комбинацией alloca() + placement new в С++. И хотя функция alloca() непосредственно не входит в стандарты C/C++, она доступна на многих платформах.
Здравствуйте, trophim, Вы писали:
T>Ну, MSVC в число поддерживающих C99 не входит?
Да. Но, строго говоря, для реализации VLA не обязательно поддерживать весь C99. MSVC и C++98 целиком не поддерживает, но это же не значит, что в нём не реализована более-менее значительная часть языка, описанная этим стандартом T>GCC я полагаю такое умеет. Да?
gcc умеет, icc умеет, clang похоже тоже умеет. MSVC видимо не умеет.
С/C++ позволяют создавать в стеке только массивы фиксированного размера.
alloca не является ни частью С, ни частью С++ поэтому наличие alloca недостаточно для опровержения этого утверждения (мало ли что можно сделать ассемблерными вставками )
а вот наличия в С99 массивов переменного размера -- достаточно.
On 17.07.2011 18:46, dilmah wrote:
> если в массиве структуры, то дырки (если они есть) есть в структуре (либо между > членами, либо паддинг в конце) -- все эти дырки учитываются в размере sizeof > структуры. А дырок между элементами массива нет в любом случае.
Я ж не говорил, что sizeof элемента массива эти дырки не учитывает.
Я говорил, что в принципе дырки есть.
Статья, достаточно хорошая... Для начинающих изучать С++ — достаточно подробно (хотя и есть ляпы: про *p++, ИМХО, проще надо было).
Вопрос к редакционной коллегии RSDN-а: можно как-нибудь ввести условный уровень знаний/умений, необходимый для познания какого-либо материала? или же класс (уровень) для кого сие чтиво предназначено?
Здравствуйте, LLI, Вы писали:
LLI>Статья, достаточно хорошая... Для начинающих изучать С++ — достаточно подробно (хотя и есть ляпы: про *p++, ИМХО, проще надо было).
Полезно и подробно — оно, конечно, да, но вот "для начинающих изучать Си++" ли? Это скорее "краткий обобщенный курс ассемблера х-86 с упрощениями", в котором для удобства видимо автора использован Си++ (на кой вообще си++ то? куда сюда лезут new()?) в качестве базового языка. Отношения к самим "плюсам" — весьма опосредствованное.
Да и к полезности, вообще, тоже: у меня помнится в детстве книжка была что-то там то ли про профессора Фортрана, то ли про путешествие каких-то детей в компьютер — по-моему там примерно такое же на примерно таком же уровне объяснялось. Разве что явно меньшим количеством текста и картинок тоже.
имхо, место данной теории в разделе "общее устройство компьютера и базовые концепции оперативной памяти и адресного пространства".