__Cheat3r |
Отправлено: 10.10.2006, 14:47 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 110
|
есть функция:
CODE |
TSomeClass *GetData(...)
{
TSomeClass * sc= new TSomeClass();
...
...
return sc;
}
|
и вторая функция:
CODE |
void CheckIt(TSomeClass * sc)
{
...
...
}
|
Вызываю как
CODE |
CheckIt(GetData(...));
|
Как мне очистить память после TSomeClass * sc= new TSomeClass(); ? После return вызывать оператор толку нет. Вызывать до, — ошибка, естественно.
Спасибо. |
|
gvg |
Отправлено: 10.10.2006, 15:37 |
|
Машинист паровоза
Группа: Участник
Сообщений: 222
|
Наверное, создать класс в GetData, использовать его сколько надо, как не нужен — удалить.
CODE |
TSomeClass *someclass = GetData(...);
CheckIt( someclass );
...
...
delete someclass;
| |
|
olegenty |
Отправлено: 10.10.2006, 15:51 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
можно обернуть в auto_ptr, тогда после последнего использования (после выхода из области видимости последнего блока, где использовался) экземпляр класса будет удалён автоматически
|
|
Gal |
Отправлено: 10.10.2006, 18:07 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 124
|
А так не пробовили?
CODE |
TSomeClass * sc= new TSomeClass();
_try
{
...
...
return sc;
}
_finally
{
delete sc;
}
| |
|
__Cheat3r |
Отправлено: 11.10.2006, 09:30 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 110
|
gvg, там скорее всего будет ошибка. Invalisd pointer operation.
olegenty, можно небольшой примерчик?
Gal, хехе. до вашего finally дело не дойдёт. |
|
__Cheat3r |
Отправлено: 11.10.2006, 09:32 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 110
|
я так понял, что делать нужно так:
CODE |
auto_ptr<TSomeClass> ptr(new TSomeClass());
|
не понятно, что делать дальше с ptr. |
|
olegenty |
Отправлено: 11.10.2006, 09:49 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
всё, что хочешь. можешь его вернуть. главное не забывать, что auto_ptr — указатель с ПЕРЕДАЧЕЙ ВЛАДЕНИЯ.
это значит:
CODE |
auto_ptr<TStringList> ptr(new TStringList()); // ptr указывает на TStringList
auto_ptr<TStringList> ptr1 = ptr; // ptr1 указывает на TStringList, а ptr указывает на фуфло
|
|
|
gvg |
Отправлено: 11.10.2006, 11:35 |
|
Машинист паровоза
Группа: Участник
Сообщений: 222
|
QUOTE (__Cheat3r @ 11.10.2006, 10:30) | gvg, там скорее всего будет ошибка. Invalisd pointer operation.
|
Это с чего же? Я исходил из того, что delete в GetData отсутствует... |
|
Shagg |
Отправлено: 11.10.2006, 14:10 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 69
|
Слуште а вам не кажется кощунством возврашать из функции указатель, который указывает на память выделяемую в самой функции
ведь не всегда происходит вызовCODE | CheckIt(GetData(...)); |
ведь функция GetData(...) может вызываться и сама по себе, и тогда программа будет безнаказанно жрать память и контролировать ее будет некому.
попробуйте возвращать не указатель, а сам объект, который точно будет разрушен при выходе из блока |
|
olegenty |
Отправлено: 11.10.2006, 14:22 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
2 Shagg — NO PROBLEM, если этот указатель "обёрнут" в auto_ptr. делаю так без зазрения совести. про проблемы с очисткой памяти ОЧЕНЬ ДАВНО забыл. потому что оператором delete не пользуюсь. зачем он, если есть auto_ptr...
|
|
gvg |
Отправлено: 11.10.2006, 16:02 |
|
Машинист паровоза
Группа: Участник
Сообщений: 222
|
QUOTE (Shagg @ 11.10.2006, 15:10) | Слуште а вам не кажется кощунством возврашать из функции указатель, который указывает на память выделяемую в самой функции
|
2Shagg
Что значитQUOTE | ведь функция GetData(...) может вызываться и сама по себе | По своему желанию?
И почему бы функции не возвращать указатель на память, выделенную в этой функции? Главное — не потерять значение этого указателя, чтобы потом освободить эту память. |
|
exp |
Отправлено: 12.10.2006, 16:25 |
|
Мастер участка
Группа: Участник
Сообщений: 304
|
Объясните, почему нельзя сделать так?
CODE |
TSomeClass *ptr=GetData();
CheckIt(ptr);
delete ptr;
|
|
|
Shagg |
Отправлено: 12.10.2006, 16:40 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 69
|
2gvg:
я имел в виду то, что функцию можно вызвать и не присваивая какойнить переменной значения, возвращаемого ею. В таком случае память действительно будет потеряна. А надеяться на то, что "я всегда буду использовать указатель, возвращаемый функцией и освобождать память" довольно глупо. Особенно если этой функцией будут пользоваться несколько человек. У них руки так и будут чесаться вызвать функцию не получив ее результата.
2olegenty: поддерживаю идею использования классов-оберток. Про auto_ptr не знал, приходилось подобные "обертки" писать самому. Спасибо за идею. |
|
__Cheat3r |
Отправлено: 12.10.2006, 18:10 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 110
|
gvg, извиняюсь.. голова уже просто забита этими указателями, delet'ами, и т.д. Вариант, конечно, сработает, но это ведь неудобно... |
|
Gal |
Отправлено: 13.10.2006, 12:53 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 124
|
QUOTE |
Gal, хехе. до вашего finally дело не дойдёт.
|
__Cheat3r — не делайте скорополительных выводов, поставте точку останова и убедитесь.
finally — отработает! |
|
__Cheat3r |
Отправлено: 13.10.2006, 13:49 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 110
|
Вобщем, насколько я понял с auto_ptr работаем так:
CODE |
TScvUsersFontInfo * FontOf(int UserID)
{
auto_ptr<TScvUsersFontInfo> out(new TScvUsersFontInfo());
out->...
out->...
return out.release();
} |
2olegenty: Так это делается?
|
|
__Cheat3r |
Отправлено: 13.10.2006, 13:57 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 110
|
Gal, действительно.
Век живи — век учись. |
|
__Cheat3r |
Отправлено: 13.10.2006, 15:12 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 110
|
Хм. или я дурак, или CodeGuard?
CODE |
The object (0x01108F60) [size: 4 bytes] was created with new
Error 00878. 0x300010 (Thread 0x0D18):
Resource leak: The object (0x4198210) was never deleted
The object (0x04198210) [size: 12 bytes] was created with new
| D:\SmartyProject\Base\includes/Windows.cpp line 28:
| TScvUserFontInfo *TScvWnds::FontOf(String Key)
| {
|> auto_ptr<TScvUserFontInfo>FontInfo(new TScvUserFontInfo());
|
|
Call Tree:
0x00405BB5(=Base.exe:0x01:004BB5) D:\SmartyProject\Base\includes/Windows.cpp#28
0x0040C3A2(=Base.exe:0x01:00B3A2) D:\SmartyProject\Base\includes/Windows.cpp#671
0x00408B83(=Base.exe:0x01:007B83) D:\SmartyProject\Base\includes/Windows.cpp#289
0x0045CD88(=Base.exe:0x01:05BD88) D:\SmartyProject\Base\FormMain.cpp#2101
0x00460316(=Base.exe:0x01:05F316) D:\SmartyProject\Base\FormMain.h#541
0x005006B4(=Base.exe:0x01:0FF6B4) Controls.pas#5143
|
Отредактировано __Cheat3r — 14.10.2006, 02:12 |
|
olegenty |
Отправлено: 13.10.2006, 15:21 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
2 __Cheat3r
нет, нет так.
вот так:
CODE |
typedef auto_ptr<ScvUsersFontInfo> ScvUsersFontInfoPtr;
ScvUsersFontInfoPtr FontOf(int UserID)
{
ScvUsersFontInfoPtr out(new TScvUsersFontInfo());
...
out->...
out->...
...
return out;
}
|
|
|