![]() |
|
Модераторы: bsa |
![]()
|
|
| EgoBrain |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 537 Регистрация: 23.3.2008 Где: Комната Репутация: нет Всего: 2 |
1). Как я понимаю байты выделились в куче, значит эту память можно освободить, как это сделать? Операции delete и delete[] крашат программу. 2). Если после арифметических операций над указателем memory_chunk я переместился в конец массива, как вернуться в начало? Предположил что возможно
казалось бы всё логично и просто - взять адрес на первый байт куска памяти, как и в случае с переменной ptr. Но почему то не срабатывает, то есть memory_chunk ничего в стандартный поток (непонятно куда теперь указывает). В то же время если memory_chunk-у присвоить значение ptr-а, то всё в порядке, и даже если не трогать memory_chunk указатель и перемещаться по памяти через ptr,а потом взять и еще раз ptr = &memory_chunk, то тоже все в проядке. Вобщем задача решается через использование дополнительной переменной, но можно же обойтись и одной поидее. 3). Как вывести адрес байта? Хотел провести элементарный эксперемент с освобождением памяти и столкнулся с кучей вопросов Это сообщение отредактировал(а) EgoBrain - 29.5.2013, 08:47 |
||||
|
|||||
| Guinness |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 310 Регистрация: 21.6.2009 Где: Зеленоград Репутация: 2 Всего: 10 |
1). В смысле выделить 10 байт и из них удалить 5? Если не ошибаюсь так делать нельзя.
2). Пример работы с указателями в посте bsa. Лично я не знаю способов без ввода ptr-а. Либо постоянно работать относительно memory_chunk, т.е. никогда не смещать указатель с начала выделенной памяти и прибавлять нужное Вам смещение. Либо запоминать смещение указателя относительно начала выделенной памяти. 3).
Забавно, через cout не получилось) Видимо я делаю что-то не так. |
|||
|
||||
| EgoBrain |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 537 Регистрация: 23.3.2008 Где: Комната Репутация: нет Всего: 2 |
Спасибо за напоминание про printf, я его не использую поэтому сразу не подумал
Спомощью него выяснилось, что судя по всему операция индексации ptr[i] скорее всего тоже самое что и ptr + i, то есть отностильено текущей позиции в массиве. Причем i может принимать отрицательные значения (сюрприз)
ptr содержит адрес первого байта куска памяти (то что нужно). Только сейчас обратил внимание, почему 24 смайла а не 10? |
|||
|
||||
| Guinness |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 310 Регистрация: 21.6.2009 Где: Зеленоград Репутация: 2 Всего: 10 |
В моем предыдущем посте я ссылочку кинул на пост, где это все расписывается) Т.е. почему цикл прошёл 24 раза, а не 10? У Вас неинициализированный массив, количество прохождения цикла может варьироваться, т.к нулевой байт может встретить как внутри массива, так и далеко вне его. |
|||
|
||||
| EgoBrain |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 537 Регистрация: 23.3.2008 Где: Комната Репутация: нет Всего: 2 |
Цикл то может и прошел N раз (выполнений программы было множество, стабильно 24 смайла записывается) это ладно, почему кусок больше выделенного размера?
Я эту тему видел, и пост bsa соответсвенно тоже, но извините, где там говорится, что индексация указателя ведется относительно текущего его "положения"? З.Ы. Касательно вопроса №1, программа крашилась видимо изза этого неправильного цикла.. |
|||
|
||||
| Guinness |
|
||||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 310 Регистрация: 21.6.2009 Где: Зеленоград Репутация: 2 Всего: 10 |
Ну, если Вы внимательно читали, то заметили бы следующее:
Вроде как, это и есть ответ на Ваш вопрос касательно того, как работают указатели.
Это же массив С, Вам никто не запрещает выйти за его пределы. Это уже на Вашей совести. Просто 24 байт от начала массива у Вас равен 0. |
||||||||
|
|||||||||
| EgoBrain |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 537 Регистрация: 23.3.2008 Где: Комната Репутация: нет Всего: 2 |
Ладно я условие цикла неверно задал и не проконтролировал выход за пределы (что еще не факт), почему cout выводит 24 байта через ptr, ведь ptr я не трогаю, он содержит правильный адрес.. З.Ы. И всё же - как вернуть ОС эти взятые в долг 10 байт? |
|||
|
||||
| feodorv |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
void * должно помочь:
Конечно, как-то нужно сохранять первоначальный указатель на выделенную память с тем, чтобы его отдать оператору delete:
Добавлено @ 04:46 Факт!!! Это сообщение отредактировал(а) feodorv - 30.5.2013, 04:49 -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||
|
|||||
| EgoBrain |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 537 Регистрация: 23.3.2008 Где: Комната Репутация: нет Всего: 2 |
Ок, спасибо участникам: я неправильно заполнил свой массив, поэтому не смог его удалить. Остались вопросы касательно адресного пространства программы
1). За его пределы выйти я не могу, тогда какие данные я перезаписал, почему это не повредило программу, она продолжила работать? 2). Как работает с памятью delete? Почему он пытается освободить не выделенные 10, а все ячейки, которые я трогал? 3). В правильном коде delete сработал, но с данным по тому же адресу все равно можно работать, как минимум читать, значит эта память все равно осталась у приложения? |
|||
|
||||
| Dem_max |
|
||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1780 Регистрация: 12.4.2007 Репутация: 4 Всего: 39 |
Потому что за пределами массива ничего не было. А если бы было то получил бы AV
Пытается все 10, что указано в таблице указателя. delete - удаляет объект (new Object) delete[] - удаляет массив объектов (new Object[10])
Да память удалилась, но она осталась, и скорее всего останется жить до конца программы или когда менеджер памяти ее не освободит для другого выделения, и повторный доступ не приведет к AV -------------------- Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte") |
||||||
|
|||||||
| EgoBrain |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 537 Регистрация: 23.3.2008 Где: Комната Репутация: нет Всего: 2 |
Dem_max, извини, но твои ответы еще кривей чем мои вопросы.
Что значит
Если она пытается удалить только 10, почему тогда delete крашит программу в этом случае?
Что там не так становится с памятью? (указатель memory_chunk яж не трогаю) Самое кривое изложение оказалось самым понятным объяснением
То есть менеджер выводит память из области приложения только тогда когда он этот кусок не решит отдать чем-то другому, поэтому кусок доступен до поры до времени? |
||||||
|
|||||||
| xvr |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 35 Всего: 223 |
Когда вы делаете new [], то менеджер памяти берет кусок свободной памяти и возвращает его вам. Но кроме этого, он (new) заказывает немного больше памяти, чем просили. И в этой дополнительной памяти он располагает информацию для менеджера памяти (в частности для того, что бы потом мог отработать delete). В частности он сохраняет размер куска памяти, ну и возможно еще что то. Все это обычно располагается непосредственно перед возвращенным вам куском памяти.
Когда вызывается delete, он читает инфо перед областью памяти, после чего просто добавляет весь кусок в список свободной памяти, что бы в дальнейшем new смог его снова вернуть. Отсюда и следуют ответы на все ваши вопросы -
За пределами области памяти, которую вам вернули, находится свободная память. Ее вернет следующий new. Вы ее потерли, но так как память там физически есть, то сам факт записи ничего не сломал. А вот структуры менеджера памяти вы поломать могли, т.к. там вполне мог оказаться элемент списка свободной памяти. Но это вы узнаете на следующем new или delete
Он вернул именно 10, так как столько и было записанно в служебной информации. Но вы могли разрушить структуры данных менеджера памяти, когда писали за пределы выделенной вам памяти. Так что последствия delete здесь непредсказуемы А куда она денется? Минимальный квант памяти, которая физически может быть выделена или отнята у приложения - 1 страница. На x86 архитектуре - это 4К памяти. Реально удалить 10 байт памяти процессор не умеет физически. |
||||
|
|||||
| Guinness |
|
||||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 310 Регистрация: 21.6.2009 Где: Зеленоград Репутация: 2 Всего: 10 |
На сколько я знаю, по запуску программы, ОС выделяет ей некое непрерывное адресное пространство, в котором данная программа должна работать. По идее, программа за пределы этого адресного пространства выйти не может, и эта память остается во владении программы до её завершения. (В старых операционках, это было возможно, т.е. можно было записать любой байт в рабочую область любой программы, в том числе и ОС, что могло привести к довольно печальным последствиям). Там может быть все что угодно. Программа не крашилась, когда Вы туда записывали эти данные, только потому что она слишком простая. Что интересно, когда я тестировал такие выделения памяти, то заметил:
Выделение памяти для одинаковых типов происходит в соседних областях. Т.е. указатель (cptr+10) у меня указывал на область памяти, где хранится ch1. Возможно, это особенности ubuntu + gcc. Не знаю).
При вызове delete[] мне пришел сигнал
Спасибо, помогло. Это сообщение отредактировал(а) Guinness - 30.5.2013, 10:25 |
||||||||
|
|||||||||
![]()
|
| Правила форума "C/C++: Для новичков" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |