所以我在C ++上是一个相当大的新手,所以我确定这是一个相对简单的问题,但我有一个遗留的C ++应用程序我正在尝试跟踪堆损坏问题并将其跟踪到此函数:
void LTrimZeros(CString *pstr)
{
char *psz1;
char *psz2;
if ( pstr->GetLength() == 0 )
return;
psz1 = new char[pstr->GetLength() + 1];
psz2 = psz1;
strcpy_s( psz2, strlen(psz2), (const char *) *pstr );
while ( *psz2 == '0' )
{
psz2++;
}
*pstr = psz2;
delete [] psz1;
return;
}
当它尝试删除psz1
时,会引发堆损坏错误。我再次对C ++很陌生,所以我不想尝试解决这个问题而不小心引入内存泄漏,所以我想我会问专家。相同功能的替代解决方案也很好,因为这个应用程序最初是用c ++ 4编写的,但现在升级到c ++ 11(还简要解释了为什么这会导致堆损坏会有很大帮助)。 / p>
答案 0 :(得分:3)
strlen(psz2)
正在读取未初始化的内存,因此可能会超出数组的末尾。这意味着传递给strcpy_s
的长度将是不可预测的,并且可能导致您在为psz1
分配的内存末尾之外写入。
假设您的功能结束有效(我不太熟悉CString可以肯定),您只需将strcpy_s
行更改为
strcpy_s( psz2, pstr->GetLength() + 1, (const char *) *pstr );
这里可能会遇到问题,win32字符串处理函数根据UNICODE
和_UNICODE
定义在8位和16位字符之间切换。我同意Alok Save和其他人的意见,转而使用std::string
会更清晰,更简单。
答案 1 :(得分:2)
来自MSDN:
errno_t strcpy_s(
char *strDestination,
size_t numberOfElements,
const char *strSource
);
在您的代码中,您在未初始化的数组上调用strlen
,您需要修复它(传递目标缓冲区可以存储的最大元素数):
strcpy_s( psz2, strlen(psz2), (const char *) *pstr );