Возврат указателя на строку из функции: memory leak?
От: S.T.A.L.I.N  
Дата: 28.06.09 21:45
Оценка:
Доброго времени суток.

Предположим у нас есть следующий код:


...

#define N <целое число>

...

wchar_t * function() {
   ...
   wchar_t * wcResult = NULL;
   ...
   wcResult = new wchar_t[N];
   ...
   return wcResult;
}


Далее:


...

wchar_t * wcSomeString = new wchar_t[N];
wcscpy_s(wcSomeString, N, function());
...

delete [] wcSomeString;


Что же получается? Память, которая выделена строке в function(), так и остаётся "висеть", т.е. Heap Memory Leak?

И ещё. Интересно, что если не копировать возвращаемую функцией строку в новую, а просто создать указатель и присвоить ему адрес возвращаемой из function() строки, то при попытке удалить такой указатель в конце блока {}:

1. В Debug режиме в VS2005 возникает Assertion на закрытие приложения: программа пытается очистить уже очищенную нами память.
2. В Release режиме в VS2005 всё в порядке.

У кого какие мысли на эту тему?
Re: Возврат указателя на строку из функции: memory leak?
От: Юрий Жмеренецкий ICQ 380412032
Дата: 28.06.09 22:10
Оценка: +1
Здравствуйте, S.T.A.L.I.N, Вы писали:
...
STA>Что же получается? Память, которая выделена строке в function(), так и остаётся "висеть", т.е. Heap Memory Leak?
Да. Можно просто 'memory leak'.

STA>И ещё. Интересно, что если не копировать возвращаемую функцией строку в новую, а просто создать указатель и присвоить ему адрес возвращаемой из function() строки, то при попытке удалить такой указатель в конце блока {}:


STA>1. В Debug режиме в VS2005 возникает Assertion на закрытие приложения: программа пытается очистить уже очищенную нами память.

STA>2. В Release режиме в VS2005 всё в порядке.

STA>У кого какие мысли на эту тему?

Я думаю что неплохо было бы увидеть код в котором все это происходит, иначе остается только предполагать...
Re: Возврат указателя на строку из функции: memory leak?
От: SeTosha  
Дата: 29.06.09 01:43
Оценка:
Здравствуйте, S.T.A.L.I.N, Вы писали:

STA>Что же получается? Память, которая выделена строке в function(), так и остаётся "висеть", т.е. Heap Memory Leak?


Да. Потому что new[] Вы вызвали два раза, а delete[] только один. Так и должно быть.

STA>И ещё. Интересно, что если не копировать возвращаемую функцией строку в новую, а просто создать указатель и присвоить ему адрес возвращаемой из function() строки, то при попытке удалить такой указатель в конце блока {}:


STA>1. В Debug режиме в VS2005 возникает Assertion на закрытие приложения: программа пытается очистить уже очищенную нами память.

STA>2. В Release режиме в VS2005 всё в порядке.

Такое обычно случается если new[] и delete[] в разных модулях (длл-ках), если речь идет про Windows.

STA>У кого какие мысли на эту тему?


Переписать функцию так чтобы она ничего не выделяла.

wchar_t * wcSomeString = new wchar_t[N];
...
function(wcSomeString, N);
...
delete [] wcSomeString;


или

Использовать строковые контейнеры std::string или CString (MFC)

или

выделять память malloc alloca
Re[2]: Возврат указателя на строку из функции: memory leak?
От: S.T.A.L.I.N  
Дата: 30.06.09 11:57
Оценка:
Благодарю.
Придётся мне кое-что переделывать)))) лики мастдай.
Re: Возврат указателя на строку из функции: memory leak?
От: Аноним  
Дата: 30.06.09 12:11
Оценка:
Здравствуйте, S.T.A.L.I.N, Вы писали:


STA>Что же получается? Память, которая выделена строке в function(), так и остаётся "висеть", т.е. Heap Memory Leak?


STA>У кого какие мысли на эту тему?


А еще есть хитрые указатели и boost::shared_array в частности(это если совсем нет желания использовать std::string).
Re: Возврат указателя на строку из функции: memory leak?
От: S.T.A.L.I.N  
Дата: 30.06.09 12:22
Оценка:
Относительно:

STA>И ещё. Интересно, что если не копировать возвращаемую функцией строку в новую, а просто создать указатель и присвоить ему адрес возвращаемой из function() строки, то при попытке удалить такой указатель в конце блока {}:


STA>1. В Debug режиме в VS2005 возникает Assertion на закрытие приложения: программа пытается очистить уже очищенную нами память.

STA>2. В Release режиме в VS2005 всё в порядке.

STA>У кого какие мысли на эту тему?



Я написал свой класс СТРОКА. Этот класс выполняет необходимые мне действия над ANSI или UNICODE строкой, указатель на которую яляется членом этого класса:


class MyString {
 LPTSTR m_lpString;
 ...
protected:
 ...
public:
 ...
 ~MyString() { delete [] m_lpString; };
 ...
 SALstring &operator=(LPTSTR lpString);
 ...
}


Как видно, класс содержит перегруженный оператор присваивания, позволяющий делать так:



LPTSTR function(...) {
 LPTSTR lpResult = NULL;
 ...
 lpResult = new TCHAR[<длина строки>];
 ...
 return lpResult;
}

...

<Глобальный блок кода>
{
 ...
 MyString mysSomeString;
 ...
 mysSomeString = function(...);
 ...
}


Понятно, что в конце "Глобального блока кода" будет автоматически вызван mysSomeString.~MyString(), который уничтожит блок динамической памяти, выделенный под строку В КЛАССЕ. По логике результат, возвращённый функцией <b>LPTSTR function(...)</b> вообще удалён не будет, что и должно бы создать LEAK.

Однако вот что привлекло моё внимание.



{
  ...
  LPTSTR lpString = NULL;
  ...
  lpString = function(...);
  ...
  delete [] lpString;   // free(lpString);
}


Подобный код

STA>1. В Debug режиме в VS2005 возникает Assertion на закрытие приложения (НАВЕРНОЕ?? программа пытается очистить уже очищенную нами память).

STA>2. В Release режиме в VS2005 всё в порядке.

Ещё одна головоломка))).
Re[2]: Возврат указателя на строку из функции: memory leak?
От: fuyant  
Дата: 01.07.09 11:49
Оценка:
Здравствуйте, SeTosha, Вы писали:

ST>или


ST>выделять память malloc alloca


а чем это поможет?
Re[2]: Возврат указателя на строку из функции: memory leak?
От: fuyant  
Дата: 01.07.09 11:53
Оценка:
Здравствуйте, S.T.A.L.I.N, Вы писали:

STA>Я написал свой класс СТРОКА. Этот класс выполняет необходимые мне действия над ANSI или UNICODE строкой, указатель на которую яляется членом этого класса:


встречайте — новый лисапед
чем вам не нравятся готовые реализации? я надеюсь, это не не коммерческий код?

STA>Подобный код


STA>>1. В Debug режиме в VS2005 возникает Assertion на закрытие приложения (НАВЕРНОЕ?? программа пытается очистить уже очищенную нами память).

STA>>2. В Release режиме в VS2005 всё в порядке.

STA>Ещё одна головоломка))).


вы бы привели полный вариант, невырезанный, а?
и функции function, и той, которая ее использует
Re[3]: Возврат указателя на строку из функции: memory leak?
От: SeTosha  
Дата: 01.07.09 12:28
Оценка:
Здравствуйте, fuyant, Вы писали:

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


ST>>или


ST>>выделять память malloc alloca


F>а чем это поможет?


х\з, но на этом странном микрософтовском компиляторе как-то помогло...
Re[4]: Возврат указателя на строку из функции: memory leak?
От: fuyant  
Дата: 01.07.09 12:39
Оценка:
Здравствуйте, SeTosha, Вы писали:

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


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


ST>>>или


ST>>>выделять память malloc alloca


F>>а чем это поможет?


ST>х\з, но на этом странном микрософтовском компиляторе как-то помогло...


помогло от чего? от мемори ликов?
вы думаете, "этот странный микрософтовский компилятор" сам вставляет вызовы free в конец блока?
Re[5]: Возврат указателя на строку из функции: memory leak?
От: SeTosha  
Дата: 01.07.09 13:24
Оценка:
Здравствуйте, fuyant, Вы писали:

ST>>>>выделять память malloc alloca

F>>>а чем это поможет?
ST>>х\з, но на этом странном микрософтовском компиляторе как-то помогло...

F>помогло от чего? от мемори ликов?

F>вы думаете, "этот странный микрософтовский компилятор" сам вставляет вызовы free в конец блока?

не, не от ликов, а от падения в дебаге.
Re[6]: Возврат указателя на строку из функции: memory leak?
От: fuyant  
Дата: 01.07.09 13:31
Оценка:
Здравствуйте, SeTosha, Вы писали:

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


ST>>>>>выделять память malloc alloca

F>>>>а чем это поможет?
ST>>>х\з, но на этом странном микрософтовском компиляторе как-то помогло...

F>>помогло от чего? от мемори ликов?

F>>вы думаете, "этот странный микрософтовский компилятор" сам вставляет вызовы free в конец блока?

ST>не, не от ликов, а от падения в дебаге.


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