То, что не описано в статье, но всех интересует
От: help-me  
Дата: 05.04.12 09:00
Оценка: :))

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

Получается, любая переменная (или указатель на переменную) кроме адреса должен хранить и тип(размер) переменной, чтобы при создании, удалении или чтении\перезаписи значения этой переменной использовать ровно столько байт, сколько есть в переменной, не больше и не меньше (но тогда на x86 размер указателя или самой переменной должен быть не 4байта(только адрес), а больше?)?

Адрес объекта является той характеристикой, которая идентифицирует объект, отличает один объект от всех других объектов в системе.

В первой цитате написано, что не только адрес, но и тип(размер) однозначно идентифицируют, тогда почему во второй цитате говорится только про адрес?

Кроме того, размер стека в большинстве случаев ограничен (для программ, разрабатываемых в среде Microsoft Visual Studio, размер стека по умолчанию — 1 Мб), что приводит к невозможности размещения в нём больших объектов, к примеру, тех же массивов.

это только в с++ ? в с# же можно большой объект разместить в стеке (например, создать структуру с множеством полей). получается , в с++ и с# разные стеки?? и почему 1 мбит? в большой программе его может не хватить даже для локальных переменных. и, то есть, стек выделяется для каждого процесса свой личный, а куча для всех процесов общая (куча — вся остальная память, не занятая стеком никакой программы)?

Возникает два вопроса: что подразумевается под термином «выделение памяти» (или «предоставление памяти») и что произойдет, если диспетчер памяти не сможет выделить блок требуемого размера?

тот же самый вопрос, если не в куче, а в стеке не хватит памяти (там же только 1 мб), то что?

Из того, что выделение памяти в стеке возлагается на компилятор, следует, что размер (а значит и тип) размещаемых в стеке объектов должен быть известен на этапе компиляции, что часто бывает невозможно. Простейшая задача обработки массива, размерность и элементы которого вводятся с клавиатуры или из файла, является ярким тому подтверждением.

когда мы читаем пользовательский ввод, мы же его присваиваем заранее созданному массиву с заданной длиной?

Надо обратить внимание на то, что при удалении адресуемого указателем p1 объекта с самим указателем p1, с его значением ничего не происходит. Оператор delete освобождает память в куче, указатель же p1 располагается в стеке, отведённая под него память будет освобождена только при выходе p1 из области видимости. В ячейках памяти, занимаемых указателем p1 в стеке (см. рис. 17), после выполнения оператора delete будет записана та же информация, что и до вызова этого оператора — число 0xF830 — адрес уже несуществующего объекта.
Таким образом, после выполнения оператора delete мы получаем недействительный указатель (dangling pointer), указатель, который адресует несуществующий объект. Разыменование такого указателя и последующий доступ к объекту в лучшем случае приведёт к немедленному аварийному завершению работы программы, в худшем — к её нестабильному поведению, которое не повторяется от одного запуска программы к другому. На выявление подобных ошибок в реальных программах зачастую уходит много времени и сил. Поэтому в тех случаях, когда планируется дальнейшая работа с указателем на удаляемый объект, имеет смысл сразу после удаления объекта присвоить указателю на него значение NULL, тем самым явно идентифицировав этот указатель как ни на что не указывающий.

А почему компилятор автоматически не присваивает ссылке NULL при операции delete?

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

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