Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Непонятки с укзателями, delete и памятью вообще 
V
    Опции темы
RenderMan
Дата 8.12.2008, 23:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 20.5.2008

Репутация: нет
Всего: нет



Решил поиздеваться над компилятором: 
Код

int main()
{
    int* a= new int(1);
    cout << *a << endl;
    delete a;
    *a =5; // я думал, что сдесь произойдет ошибка выполнения
    cout << *a << endl;
    return 0;
}



не ту-то было, ошибки не произошло, что вообще логично, т.к. указатель указывает на какую-то область памяти, и мы вправе делать с этой памятью все, что захотим(или нет?).

Теперь немного модифицируем код:
Код

int main()
{
    int* a= new int(1);
    cout << a << endl;
    delete a;
    *a =5;
    //ADDED------>>>>>
    int* b = new int(4);
    return 0;
}




теперь программа ругается(SIGSEGV). Еще немного изменим код:
Код

int main()
{
    int* a= new int(1);
    cout << a << endl;
    delete a;
    //*a =5;
    //ADDED------>>>>>
    int* b = new int(4);
    cout << b << endl;
    return 0;
}

на консоль выводятся одинаковые числа, т.е. выделяется одна и та же память. Но почему проге все нравится, пока я делаю,что хочу с НЕПРИНАДЛЕЖАЩЕЙ ей памятью , а потом, когда мы выделяем ей совершенно легально ту самую память, она начинает ругаться? Каким образом куча узнает, что я что-то делал со свободной памятью, или она ведет какой-то ее мониторинг? Хочу обратить внимание,что крэш идет именно на выделении памяти под b.  Или может быть так,что,например, куча считает,что это нрмальная ячейка памяти, но когда она(куча) просит ее выделить у системы, та ей говорит, что, мол, только что к ней обращялись, и поэтому я тебе эту память не отдам.
Разъясните, пожалуйста, по-моему, это важный вопрос.
PM MAIL   Вверх
Dmi3ev
Дата 9.12.2008, 01:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

Репутация: 13
Всего: 41



Цитата

    *a =5; // я думал, что сдесь произойдет ошибка выполнения

Почему?
Цитата

delete a;

Мы освобождаем участок памяти, адрес которой хранится в указателе, но указатель остается, мы его-то не удаляем никуда, можем поменять адрес.
И чего тут такого великого???


--------------------

PM MAIL   Вверх
J0ker
Дата 9.12.2008, 05:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 9
Всего: 14



Цитата(RenderMan @  8.12.2008,  23:17 Найти цитируемый пост)
не ту-то было, ошибки не произошло

это вам просто повезло

Цитата(RenderMan @  8.12.2008,  23:17 Найти цитируемый пост)
что вообще логично, т.к. указатель указывает на какую-то область памяти

любой указатель указывает на какую-то область памяти
с вышеозначеным явлением это никак не связано

Цитата(RenderMan @  8.12.2008,  23:17 Найти цитируемый пост)
и мы вправе делать с этой памятью все, что захотим(или нет?)

или нет

Цитата(RenderMan @  8.12.2008,  23:17 Найти цитируемый пост)
теперь программа ругается(SIGSEGV)

это не программа ругается, а процессор

дальнейший бред не понят, сорри  smile 


--------------------
user posted image
PM MAIL   Вверх
MAKCim
Дата 9.12.2008, 09:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 2
Всего: 207



Цитата(J0ker @  9.12.2008,  05:52 Найти цитируемый пост)
это не программа ругается, а процессор

процессор SIGSEGV'ами не ругается  smile 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
ksili
Дата 9.12.2008, 10:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: нет
Всего: 17



Что такое SIGSEGV я не знаю, но думаю дело такое:

В первом коде память освобождена и пока никем не занята, ук-ль a указывает на неё, т.к. его значение не изменилось, через него работаем с этой памятью

Во втором коде память освобождена, потом выделена заново, и получилось, что a указывает уже на чужую память, а не на свободную или свою. Видимо поэтому и произошла ошибка.

В третьем случае, ничего непонятного. Просто получилось так, что b выделилось на месте a. Просто совпадение.


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
mes
Дата 9.12.2008, 10:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(ksili @  9.12.2008,  10:02 Найти цитируемый пост)

Во втором коде память освобождена, потом выделена заново, и получилось, что a указывает уже на чужую память, а не на свободную или свою. Видимо поэтому и произошла ошибка.

нет.. во всех случаях просто совпадение. Система не всегда может определить запись программы не в "свою" память - один и тот же пример в разных контекстах может давать разный результат. 



--------------------
PM MAIL WWW   Вверх
Dmi3ev
Дата 9.12.2008, 13:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

Репутация: 13
Всего: 41



RenderMan, в принципе можно разбить молотком монитор и радоваться тому, что можешь делать все что угодно не только с памятью, но и с монитором  smile 
А можно пойти и дальше, выйти во двор и разбить лобовое стекло первому попавшемуся автомобилю и радоваться тому, что ты можешь делать все что угодно и с ним  smile
Главное думать о последствиях  smile 
Все, что ты делаешь обязательно приведет к проблемам, даже если это все прокатило на твоем компиляторе, если твоя программа будет немного длиннее и функциональнее  smile
Вообщем, повелитель памяти... Попробуй сделать прогу на основе своих извращений и все станет ясно... 


--------------------

PM MAIL   Вверх
xvr
Дата 9.12.2008, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Все очень просто: когда ты сделал int* a= new int(1); crt выделила кусок памяти и вернула его адрес, который затем попал в a. Реальный размер выделенного участка, а равно как и его реальное начало в памяти, не обязаны совпадать с тем, что ты запрашивал. Скорее всего, будет выдеден блок байт так в 8-16, и перед a еще будет байт 8 с размером выделенного участка.
Затем ты делаешь delete a;, память, ранее занимаемая этим блоком, возвращается в пул свободной памяти. При этом этот блок провязывается в списки свободной памяти, для указателей этих списков используется тело блока (это можно сделать, т.к. приложение аернуло эту память, и crt имеет право распоряжаться ей по своему усмотрению)
Затем, ты делаешь *a =5;, перезаписывая таким образом один из указателей списка свободной памяти своей 5кой. Список свободных блоков разрушен  smile  Последующий вызов int* b = new int(4); приведет к краху менеджера памяти, когда он попытается найти свободный блок, обходя список этих блоков по разрушеннему списку, что ты и получил в виде SIGSEGV

PM MAIL   Вверх
J0ker
Дата 9.12.2008, 19:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 9
Всего: 14



Цитата(MAKCim @  9.12.2008,  09:48 Найти цитируемый пост)
процессор SIGSEGV'ами не ругается

процессор ругается протекшен-фолтами, которые транслируются ОС в SIGSEGV
ты удовлетворен?  smile 

Это сообщение отредактировал(а) J0ker - 9.12.2008, 19:05


--------------------
user posted image
PM MAIL   Вверх
RenderMan
Дата 9.12.2008, 21:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 20.5.2008

Репутация: нет
Всего: нет



Извращался я не потому что писал прогу, а хотел понять механизм выделения памяти с помощью крэшей). Весь вопрос собственно заключался в следующем: каким макаром мех-изм выделения памяти узнает,что я что-то делал со свободной памятью. по-моему, xvr все объяснил, за что ему отднльная благодарность).  Всем спасибо)
PM MAIL   Вверх
taiven
Дата 11.12.2008, 02:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 302
Регистрация: 30.6.2008

Репутация: 2
Всего: 9



Цитата(RenderMan @  8.12.2008,  22:17 Найти цитируемый пост)
Решил поиздеваться над компилятором: 

вот это мне кажется поинтересней будет  smile 
Код

    int *a = new int(1);
    int *b = a;
    delete a;

    int *c = new int(5);

    delete b;

    int *d = new int(10);

    std::cout << "c = " << *c << '\n';


Это сообщение отредактировал(а) taiven - 11.12.2008, 02:01
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0568 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.