删除[]堆损坏错误

时间:2013-04-22 15:15:42

标签: c++ c++11 mfc cstring heap-corruption

所以我在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>

2 个答案:

答案 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 );