я начинаю с очень простой программой:Изменение размера динамической строки вызывает утечку памяти
#include <TBString.h>
int main(int argv, char** argc)
{
tb::String test("");
test = "Hello World!";
return 0;
}
tb::String
мой собственный класс строки, которая была разработана для обработки как char
строк и wchar_t
(Unicode) строк. Он сильно замаскирован, tb::String
- это typedef tb::StringBase<char>
.
Все это скомпилировано с использованием утилит для отладки CRT для проверки утечек памяти. Вот результат:
Detected memory leaks!
Dumping objects ->
c:\users\sam\svn\dependencies\toolbox\headers\tbstring2.inl(38) : {442} normal block at 0x00D78290, 1 bytes long.
Data: < > 00
{131} normal block at 0x00C5EFA0, 52 bytes long.
Data: < > A0 EF C5 00 A0 EF C5 00 A0 EF C5 00 CD CD CD CD
Object dump complete.
Detected memory leaks!
Dumping objects ->
c:\users\sam\svn\dependencies\toolbox\headers\tbstring2.inl(38) : {442} normal block at 0x00D78290, 1 bytes long.
Data: < > 00
Object dump complete.
The program '[2888] SAM_release.exe: Native' has exited with code 0 (0x0).
Так это выглядит как пустой Тб :: String (с размером 0) вызывает утечку памяти. Подтвержденные с этой программой, которая не утечка:
#include <TBString.h>
int main(int argv, char** argc)
{
tb::String test("Hello World!");
return 0;
}
стек вызовов для оригинальной программы:
- Создайте
StringBase<char>
шпагатом""
. m_Length
устанавливается в 0.m_Maximum
установлен вm_Length + 1
(1).m_Data
создан с длинойm_Maximum
(1).m_Data
очищается и заполняется""
._AppendSingle
установлен вStringBase<char>::_AppendDynSingle
.- Перегруженный оператор
StringBase<char>::operator =
называется бечевкой"Hello World!"
_AppendSingle
называется.m_Length
равно 0, равно 1.m_Maximum
checklen
установлен вm_Length + src_len + 1
(13).m_Maximum
умножается на 2, пока оно больше, чемchecklen
(16).- Функция
StringBase<char>::Resize
вызывается с новым максимумом.
Resize функция:
template <typename C>
TB_INLINE StringBase<C>& StringBase<C>::Resize(int a_Maximum /*= -1*/)
{
if (!m_Data)
{
m_Maximum = (a_Maximum == -1) ? 4 : a_Maximum;
m_Data = new C[m_Maximum];
StringHelper::Clear<C>(m_Data, m_Maximum);
}
else
{
int newmax = (a_Maximum == -1) ? (m_Maximum * 2) : a_Maximum;
C* temp = new C[newmax];
StringHelper::Clear<C>(temp, newmax);
if (m_Length > 0) { StringHelper::Copy(temp, m_Data, m_Length); }
delete [] m_Data;
m_Data = temp;
m_Maximum = newmax;
}
return *this;
}
Это то, что я подозреваю, что это проблема. Теперь, мой вопрос будет:
Как я могу перераспределить память на C++ без его запуска утечки памяти в отладчике CRT?
Конструктор:
TB_INLINE StringBase<char>::StringBase(const char* a_String)
{
m_Length = StringHelper::GetLength<char>(a_String);
m_Maximum = m_Length + 1;
m_Data = new char[m_Maximum];
StringHelper::Clear<char>(m_Data, m_Maximum);
StringHelper::Copy<char, char>(m_Data, a_String, m_Length);
_AppendSingle = &StringBase<char>::_AppendDynSingle;
_AppendDouble = &StringBase<char>::_AppendDynDouble;
}
деструктор:
TB_INLINE StringBase<char>::~StringBase()
{
if (m_Data) { delete [] m_Data; }
}
Назначение Оператор:
TB_INLINE StringBase<char>& StringBase<char>::operator = (const char *a_String)
{
Clear();
return (this->*_AppendSingle)(a_String);
}
Дозапись функции:
template<>
TB_INLINE StringBase<char>& StringBase<char>::_AppendDynSingle(const char* a_String)
{
if (!a_String) { return *this; }
int src_len = StringHelper::GetLength<char>(a_String);
// check size
if (m_Maximum == -1)
{
m_Maximum = src_len + 1;
m_Data = new char[m_Maximum];
StringHelper::Clear<char>(m_Data, m_Maximum);
m_Length = 0;
}
int checklen = m_Length + src_len + 1;
if (checklen > m_Maximum)
{
while (checklen > m_Maximum) { m_Maximum *= 2; }
Resize(m_Maximum);
}
// append
strcat(m_Data, a_String);
// new length
m_Length += src_len;
return *this;
}
Обратите внимание: я не хочу использовать std::string
или std::vector
, я хочу исправить эту функцию.
Этот вопрос, в основном, относится к классу 'tb :: String'. Это один из ваших собственных сейчас или из какой-то библиотеки? – leftaroundabout
Что такое 'tb :: String'? Что-то серьезное, или что-то, что вы взломали? –
'tb :: String' - мой собственный динамический класс строк. Я могу опубликовать полный источник, если потребуется, но я считаю, что я вставил наиболее важные биты. – knight666