Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

борьба с Memory leak

292
01 сентября 2005 года
Matush
726 / / 14.01.2004
void DoSome()
{
LPSTR* Lec;
int Total;
g_Data->GetAllLectors(&Lec, &Total);
for(int y=0; y<Total; y++)
{
ListView->InsertItem(y, Lec[y], y+1); }
delete[] Lec[0]; // Ошибка
}

При выполнении этого кода происходит ошибка при освобождении памяти. С чем это может быть связано?

Функция GetAllLectors просто копирует в Lec некоторые данные.
299
01 сентября 2005 года
3D Bob
885 / / 18.04.2005
Цитата:
Originally posted by Matush
void DoSome()
{
LPSTR* Lec;
int Total;
g_Data->GetAllLectors(&Lec, &Total);
for(int y=0; y<Total; y++)
{
ListView->InsertItem(y, Lec[y], y+1); }
delete[] Lec[0]; // Ошибка
}

При выполнении этого кода происходит ошибка при освобождении памяти. С чем это может быть связано?

Функция GetAllLectors просто копирует в Lec некоторые данные.



А тем что указатель создан...
LPSTR* Lec; и хер знает на что он указывает. И память под него не отведена.
и создан он не динамически чтобы использовать delete и не является массивов.

И насколько я помню LPSTR это уже указтель... И того ты создаешь указатель на указатель...
кароче LPSTR равносильно char *

И того твой LPSTR* Lec;
Равносилен char ** Lec;


Делай так.

 
Код:
void DoSome()
{
    char Lec[10];
    int Total;
    g_Data->GetAllLectors(Lec, &Total);
    for(int y=0; y<Total; y++)
    {
        ListView->InsertItem(y, Lec[y], y+1);   }

}


Память сама освободится после выполнения функции.
Ты же создаешь не через new...

Или так если уж ухота удалять все самому....
Код:
void DoSome()
{
    char * Lec = new char[10]
    int Total;
    g_Data->GetAllLectors(Lec, &Total);
    for(int y=0; y<Total; y++)
    {
        ListView->InsertItem(y, Lec[y], y+1);   }
delete[] Lec;

}
292
01 сентября 2005 года
Matush
726 / / 14.01.2004
Я в прошлом примере не полностью описал картину (я в курсе что такое LPSTR и память под него все нормально выделяется).

Вот полный пример (он не с LPSTR, но аналогичен):

void DoSome()
{
int* pID;
Get1(&pID);
delete[] pID;
}

// это метод класса для работы с данными
void Data::Get1(int ** pID)
{
Get2(pID);
}


// это метод класса, который находится в COM объекте
STDMETHODIMP IData::Get2(int** pID)
{
*pID = new int[nSize];
for(int y=0; y<nSize; y++)
{
(*pID)[y] = 2; // 2 тут ради примера
}
}

так вот, в функции DoSome() происходит ошибка при выполнении delete[] pID;
299
01 сентября 2005 года
3D Bob
885 / / 18.04.2005
Код:
Get2(int** pID){
      *pID = new int[10];
      for(int y=0; y<10; y++){
            (*pID)[y] = 2; // 2 тут ради примера
      }
}

void Get1(int ** pID){
      Get2(pID);
}

void DoSome(){
        int* pID;
        Get1(&pID);
        delete[] pID;
}

int main(int argc, char* argv[]){
      DoSome();
      return 0;

}


Прекрасно работает.
292
01 сентября 2005 года
Matush
726 / / 14.01.2004
Цитата:
Originally posted by 3D Bob
Прекрасно работает.



Едрен-батон. Что же делать?
Оно-то работает прекрасно когда все в одном модуле. Но функция IData::Get2(int** pID) находится в СОМ объекте (DLL), и уже при таком раскладе, как я говорил происходит эррор (delete[] pID). Видимо после выхода из функции, память на которую указывает указатель остается в использовании этого СОМ объекта.

Вопрос остается актуален - ЧТО ДЕЛАТЬ?

4.7K
02 сентября 2005 года
kelz
42 / / 21.06.2004
Ясен пень, ты память выделять не выделяешь, а удаляешь. У тебя тут два пути: или выделяй память, или не удаляй тогда ее. (первый правильней)
 
Код:
void DoSome()  
{  
   int* pID = new[/*сколько надо*/];  
   Get1(&pID);  
   delete[] pID;  
}
292
02 сентября 2005 года
Matush
726 / / 14.01.2004
Цитата:
Originally posted by kelz
Ясен пень, ты память выделять не выделяешь, а удаляешь.
 
Код:
void DoSome()  
{  
   int* pID = new[/*сколько надо*/];  
   Get1(&pID);  
   delete[] pID;  
}



Едрена вошь! Как это не выделяю память,
а это вот что: ??
Get2(int** pID){
*pID = new int[10]; // ВОТ ТУТ ПАМЯТЬ ВЫДЕЛЯЕТСЯ
//// skip
}

Выделять память наперед нельзя (точнее не надо)

299
02 сентября 2005 года
3D Bob
885 / / 18.04.2005
Я тут вот что подумал.
Адресации внутри объекта ядра, возможно не совпадает с адресацией в твоей программе.
Но это очень врятли... Сомневаюсь...

Нету причин этумо быть. Приведи еще более больший код. С момента создания ком объекта.
Я правда еще в изучении до них не дошел. Но это дело времени. А сейчас вот посмотрю.
3
02 сентября 2005 года
Green
4.8K / / 20.01.2000
В каждом модуле (EXE, DLL и т.п.) свой менеджер памяти.
Если память была выделена одним менеджером, то и освобождена она должна быть только этим менеджером.

В твоем случае нужно сделать так:
void DoSome()
{
int* pID = Get();
Delete(pID);
}

где Get и Delete - методы, находящиеся в одном модуле, для выделения и освобождения памяти соотв-но.
299
02 сентября 2005 года
3D Bob
885 / / 18.04.2005
Цитата:
Originally posted by Green
В каждом модуле (EXE, DLL и т.п.) свой менеджер памяти.
Если память была выделена одним менеджером, то и освобождена она должна быть только этим менеджером.

В твоем случае нужно сделать так:
void DoSome()
{
int* pID = Get();
Delete(pID);
}

где Get и Delete - методы, находящиеся в одном модуле, для выделения и освобождения памяти соотв-но.


Я был прав)))) Даж приятно):D

292
03 сентября 2005 года
Matush
726 / / 14.01.2004
Цитата:
Originally posted by Green
В каждом модуле (EXE, DLL и т.п.) свой менеджер памяти.



Большое спасибо. Сейчас все работает как часы.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог