Очистка памяти после потока
От: olegto  
Дата: 29.01.07 13:06
Оценка:
Создаю структуру, отправляйю в поток, поток обрабатывает и взвращает ее.
При закрытии программы CodeGuru ругается на то что память не от-delete-ина.

Resource leak in process: Project1.exe(3372)  - C:\Oleg\B_Sorces\SNMP\Tread\SNMP_rutine.h#734  The object array (0xF78E38) was never deleted
The object array (0xF78E38) was never deleted
The object array (0x00F78E38) [size: 16 bytes] was created with new[]
0x004078F1 - C:\Oleg\B_Sorces\SNMP\Tread\SNMP_rutine.h#734
0x7C80B683


Вопрос в том где и когда я должен ее убивать ?



Структура:
struct SNMP_IP_Table
{
AnsiString Host;
AnsiString Community;
int retries;
int timeout;
int Return_Status;
AnsiString Error_Description;
int Count;
AnsiString *AdEntAddr;
AnsiString *AdEntIfIndex;
AnsiString *AdEntNetMask;
};


Заполнение, запуск и отображение:
SNMP_IP_Table * IP_Table;
...

void __fastcall TForm1::Button8Click(TObject *Sender)
{
IP_Table = new SNMP_IP_Table;

IP_Table->Host = ComboBox1->Text;
IP_Table->Community = "public";
IP_Table->timeout = 1000;
IP_Table->retries = 1;

IP_Table_Thread=CreateThread(NULL,0,GetIP_Table,(LPVOID)IP_Table,0,&IP_Table_ThreadId);


ULONG IP_T;
do    {
    GetExitCodeThread(IP_Table_Thread, &IP_T);
    Sleep(200);
    Application->ProcessMessages();
    if(IP_T != STILL_ACTIVE) Label1->Caption = "IP_Table_Thread - OK";

while (IP_T == STILL_ACTIVE);

TerminateThread(IP_Table_Thread, IP_Table_ThreadId);
IP_Table_Thread=NULL;

Memo1->Lines->Add("IP_Table");
for (int i = 0; i <= IP_Table->Count; i++)
    {
    Memo1->Lines->Add("");
    Memo1->Lines->Add(IntToStr(i) + " Addr " + IP_Table->AdEntAddr[i]);
    Memo1->Lines->Add(IntToStr(i) + " NetMask " + IP_Table->AdEntNetMask[i]);
    Memo1->Lines->Add(IntToStr(i) + " IfIndex " + IP_Table->AdEntIfIndex[i]);
    }

}



Поток:
unsigned long __stdcall  GetIP_Table(void * par)
{

...
IP_Table->Count = VarDim;
IP_Table->AdEntAddr = new AnsiString[VarDim+1];
IP_Table->AdEntIfIndex = new AnsiString[VarDim+1];
IP_Table->AdEntNetMask = new AnsiString[VarDim+1];
...

}
Re: Очистка памяти после потока
От: olegto  
Дата: 29.01.07 13:16
Оценка:
Блин CodeGuru а CodeGuard...
Re: Очистка памяти после потока
От: Аноним  
Дата: 29.01.07 14:07
Оценка:
>TerminateThread(IP_Table_Thread, IP_Table_ThreadId);
Поубивал бы
Re[2]: Очистка памяти после потока
От: olegto  
Дата: 29.01.07 14:12
Оценка:
Здравствуйте, Аноним, Вы писали:

>>TerminateThread(IP_Table_Thread, IP_Table_ThreadId);

А>Поубивал бы

В каком смысле ?
Re[3]: Очистка памяти после потока
От: Аноним  
Дата: 29.01.07 14:59
Оценка:
Здравствуйте, olegto, Вы писали:

>>>TerminateThread(IP_Table_Thread, IP_Table_ThreadId);

А>>Поубивал бы
O>В каком смысле ?
В случае TermnateThread не вызываются деструкторы объектов, созданных на стеке. И происходят прочие гадости(подробнее — у Рихтера)
Re[4]: Очистка памяти после потока
От: olegto  
Дата: 29.01.07 16:05
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, olegto, Вы писали:


>>>>TerminateThread(IP_Table_Thread, IP_Table_ThreadId);

А>>>Поубивал бы
O>>В каком смысле ?
А>В случае TermnateThread не вызываются деструкторы объектов, созданных на стеке. И происходят прочие гадости(подробнее — у Рихтера)

Без TerminateThread(IP_Table_Thread, IP_Table_ThreadId); CodeGuide также ругается при выходе программы.
Если вручную пытаюсь убить delete[] IP_Table; то происходит "Abnormal program termination".

PS
Если не запускать поток, то delete[] IP_Table; происходит без ошибок.
Re[5]: Очистка памяти после потока
От: Аноним  
Дата: 29.01.07 16:14
Оценка:
Здравствуйте, olegto, Вы писали:

O>Здравствуйте, Аноним, Вы писали:


А>>Здравствуйте, olegto, Вы писали:


>>>>>TerminateThread(IP_Table_Thread, IP_Table_ThreadId);

А>>>>Поубивал бы
O>>>В каком смысле ?
А>>В случае TermnateThread не вызываются деструкторы объектов, созданных на стеке. И происходят прочие гадости(подробнее — у Рихтера)

Ну если программу не запускать, то вообще никто ругаться не будет.
Тоже решение

O>Без TerminateThread(IP_Table_Thread, IP_Table_ThreadId); CodeGuide также ругается при выходе программы.

Потому что объект не уничтожаешь.

O>Если вручную пытаюсь убить delete[] IP_Table; то происходит "Abnormal program termination".

Потому что пытаешься использовать объект после того, как ты его убил.

O>PS

O>Если не запускать поток, то delete[] IP_Table; происходит без ошибок.
Потому что ты знаешь, когда тебе больше IP_Table не нужен и не пытаешься его пользовать
после того, когда он уничтожен.

На самом деле что с потоками, что без них правила создания и уничтожения объектов
в куче одинаковы.
Уничтожай объект тогда, когда он не нужен и пытайся его использовать после того,
как он уничтожен. Все просто ведь?
Потоки только усложняют анализ, когда и где что используется.

P.S. Потоки прибивать начильно и в самом деле не надо.
Надо дожидадаться их окончания.
См на WaitForSingleObject
Re[6]: Очистка памяти после потока
От: olegto  
Дата: 29.01.07 17:00
Оценка:
Хмм проблема решиолась вот таким кодом:

delete [] IP_Table->AdEntAddr;
delete [] IP_Table->AdEntNetMask;
delete [] IP_Table->AdEntIfIndex;
delete IP_Table;
Re[7]: Очистка памяти после потока
От: Аноним  
Дата: 29.01.07 23:14
Оценка: +1
Здравствуйте, olegto, Вы писали:

O>Хмм проблема решиолась вот таким кодом:


O>
O>delete [] IP_Table->AdEntAddr;
O>delete [] IP_Table->AdEntNetMask;
O>delete [] IP_Table->AdEntIfIndex;
O>delete IP_Table;
O>


Сделал бы ты нормальный деструктор.
Тогда хватило бы delete IP_Table
Ты ведь на C++ пишешь?

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