누출이 발생합니다. 무겁게 템플릿 화 된 tb::String
은 tb::StringBase<char>
의 typedef입니다.동적 문자열 크기를 조정하면 메모리 내가 아주 간단한 프로그램으로 시작
모든 것은 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).
tb : String (크기가 0 인)이 메모리 누수의 원인이되는 것처럼 보입니다.
#include <TBString.h>
int main(int argv, char** argc)
{
tb::String test("Hello World!");
return 0;
}
콜 스택을 원래 프로그램 :
- 문자열
""
와StringBase<char>
만들기 누설하지 않습니다이 프로그램으로 확인했다. m_Length
가 0m_Maximum
로 설정m_Length + 1
가 설정된다 (1).- 은 길이가
m_Maximum
(1)으로 생성됩니다. - 은 지워지고
""
으로 채워집니다. _AppendSingle
은StringBase<char>::_AppendDynSingle
으로 설정됩니다.- 오버로드 된 연산자
StringBase<char>::operator =
은 문자열"Hello World!"
_AppendSingle
과 함께 호출됩니다.m_Length
는m_Maximum
1.checklen
는m_Length + src_len + 1
(13)로 설정하고, 0이다.m_Maximum
은checklen
(16)보다 커질 때까지 2를 곱합니다.StringBase<char>::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;
}
이 제가 생각하는 문제입니다. 자, 내 질문은 다음과 같습니다 :
CRT 디버거에서 메모리 누수를 유발하지 않고 어떻게 C++에서 메모리를 재 할당 할 수 있습니까?
생성자 :
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;
}
,174,
참고 : std::string
또는 std::vector
을 사용하고 싶지 않습니다.이 기능을 수정하고 싶습니다.
그 질문은 대부분'tb :: String' 클래스에 관한 것 같습니다. 이 카드는 지금 자신의 카드인가요, 아니면 도서관의 카드인가요? – leftaroundabout
'tb :: String'이란 무엇입니까? 진지한 것, 해킹 한 것? –
'tb :: String'은 제 자신의 동적 문자열 클래스입니다. 필요한 경우 전체 소스를 게시 할 수 있지만 가장 관련성이 높은 비트를 붙여 넣었다고 생각합니다. – knight666