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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Стек и куча, совсем простой вопрос. 
:(
    Опции темы
alex7851
Дата 28.4.2012, 17:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Всем привет. Допустим, вот такой класс:
Код

class mycls
{
public:
int a;
int* b;
mycls();
}

mycls::mycls()
{
b = new int;
}

И такой код:
Код

mycls obj1;
mycls* obj2 = new mycls;

Скажите, верно ли я понимаю:
Объект obj1 будет создан в стеке; он состоит из членов int и int*, которые будут созданы в стеке. Также, в куче будет создан еще объект типа int.
Объект obj2 будет создан в куче; то есть его члены a и b будут тоже в куче. При этом тоже еще где-то в куче будет создан еще один int.

И скажите еще вот что. Вот такой код:
Код


class GP
{
    public:
    void* FP;
    GP();
    ~GP();
};

GP::GP()
{
    FP = malloc ( 500000 );
}

GP::~GP()
{
    free( this->FP );
}

int main()
{
    GP a;
    getch();
    free( a.FP );
    getch();
}

Ни вызов free, ни ручной вызов деструктора для a не освобождают память, выделенную под FP. Почему?
PM MAIL   Вверх
disputant
Дата 28.4.2012, 20:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(alex7851 @ 28.4.2012,  17:12)

Скажите, верно ли я понимаю:
Объект obj1 будет создан в стеке; он состоит из членов int и int*, которые будут созданы в стеке. Также, в куче будет создан еще объект типа int.
Объект obj2 будет создан в куче; то есть его члены a и b будут тоже в куче. При этом тоже еще где-то в куче будет создан еще один int.

Ну, если оператор new не переопределен, то, как мне кажется, все так.
Цитата(alex7851 @ 28.4.2012,  17:12)

Ни вызов free, ни ручной вызов деструктора для a не освобождают память, выделенную под FP. Почему?


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

Но в коде я не вижу проверки освобождения - как вы убедились, что освобождение памяти не прошло?

И еще - путать в одном коде new и malloc - не комильфо smile

Это сообщение отредактировал(а) disputant - 28.4.2012, 20:55
PM MAIL   Вверх
alex7851
Дата 28.4.2012, 21:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(disputant @ 28.4.2012,  20:52)
Но в коде я не вижу проверки освобождения - как вы убедились, что освобождение памяти не прошло?

Я смотрю ProcessExplorer'ом, сколько памяти уходит на процесс. Дело в том, что если написать так:
Код

void* ptr = malloc ( 500000 );
getch();
free ( ptr );
getch();

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

Вообще, тут ситуация такая - сам объект класса лежит в стеке, и содержит член, указывающий на большой кусок в куче. При создании объекта, конструктор выделяет память. Дальше наступает момент, когда объект более не нужен. Как вызвать деструктор и его уничтожить? Ведь, например, delete должен работать в связке с new, то есть высвобождать память, выделенную new и вызывать деструктор. У меня в стеке сам объект, нельзя его удалить.
Вопрос чисто академический, чтобы разобраться, я уже по другому реализовал.

Цитата(disputant @ 28.4.2012,  20:52)
И еще - путать в одном коде new и malloc - не комильфо smile

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


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 4.8.2008
Где: г. Таганрог

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



Код

GP::~GP()
{
    free( this->FP );
}

free( a.FP );


Это черевато, в деструкторе будет попытка освободить уже освобожденую память.
И потом вызов free не гарантирует возврат памяти системе, она можео остаться зарезервированной за процессом, на случай если еше понадобится. По моему так
PM MAIL   Вверх
feodorv
Дата 29.4.2012, 01:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



Цитата(alex7851 @  28.4.2012,  22:39 Найти цитируемый пост)
а в том варианте она не освобождается после вызова деструктора.

А в какой момент вызывается деструктор?

Цитата(alex7851 @  28.4.2012,  18:12 Найти цитируемый пост)
int main()
{
    GP a;
    getch();
}


А вызывается он уже после getch() smile И заметить этот момент ProcessExplorer'ом практически невозможно, ибо он совпадает с моментом завершения процесса.

Ну и про malloc/free вместо new/delete и про двойное высвобождение памяти Вам уже написали))))

Это сообщение отредактировал(а) feodorv - 29.4.2012, 01:58


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
disputant
Дата 29.4.2012, 07:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Во-первых, при освобождении память не обязательно сразу возвращается системе, так что это способ проверки, мягко говоря, ненадежный.
Во-вторых, деструктор объекта вызывается при выходе из области видимости, так что в своем коде вы вызов деструктора не видите вообще. Для этого лучше было бы так:

Код

int main()
{
    {
        GP a;
    } // Вот тут и вызывается деструктор
    getch();
}


Впрочем, черасчур умный оптимизатор может и тут все испортить (хотя если умный, то как раз не должен smile)

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


Новичок



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

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



Спасибо за ответы.

Цитата(feodorv @ 29.4.2012,  01:57)
А вызывается он уже после getch() smile И заметить этот момент ProcessExplorer'ом практически невозможно, ибо он совпадает с моментом завершения процесса.

Не, я имел в виду, если вот эту строчку - free( a.FP ); заменить на a.~GP(); то не видно освобождения. Если вызывать деструктор выходом из области видимости, та же фигня.

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

Ясно, а надежней можно как-нибудь?
PM MAIL   Вверх
disputant
Дата 29.4.2012, 13:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(alex7851 @ 29.4.2012,  10:12)
Ясно, а надежней можно как-нибудь?

Что-то типа функций heapwalk, heapchk в вашем компиляторе нет?
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

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

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

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

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


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

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


 




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


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

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