【问题标题】:Heap corruption error with delete []删除 [] 导致的堆损坏错误
【发布时间】:2013-04-15 13:28:54
【问题描述】:

所以我是 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(另外简要解释一下为什么会导致堆损坏会有很大帮助)。

【问题讨论】:

  • 那是生产代码吗?
  • 使用std::string句号!摆脱所有指针的混乱。
  • 在 whilte 循环中,是 *psz2 == '0' 吗?或者你的意思是 *psz2 == '\0'
  • psz1 从未使用过,psz2 将自己分配给psz1。您是否检查过 GetLength() 返回的大小是否有效? strlen 呢?没有办法正常工作。你已经知道尺寸了,为什么不使用pstr->GetLength() + 1 作为你的长度呢?
  • 是的,它是生产代码,这个应用程序早于 std::string 我相信要全部替换它会做很多工作,它正在删除 0 而不是寻找空终止符,是的 GetLength 是返回正确的值。

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


【解决方案1】:

strlen(psz2) 正在读取未初始化的内存,因此可能会读取超出数组末尾的内容。这意味着您传递给strcpy_s 的长度将是不可预测的,并且可能导致您写入超出为psz1 分配的内存的末尾。

假设你的函数结束是有效的(我对CString 不太熟悉,可以肯定地说),你可以简单地将你的strcpy_s 行更改为

strcpy_s( psz2, pstr->GetLength() + 1, (const char *) *pstr );

根据UNICODE_UNICODE 的定义,您可能会遇到win32 字符串处理函数在8 位和16 位字符之间切换的问题。我同意 Alok Save 和其他人的观点,即改用 std::string 会更清晰、更简单。

【讨论】:

  • *pstr = psz2; 怎么样? CString 支持吗?不。
  • @trojanfoe,Oblivious 上尉 我还没有完成这个功能。我会相应地改写我的答案。
  • psz2 = psz1; 不是说psz2 指向psz1,而这只是newed up?
  • 我很想将它切换到 std::string,但我们说的是 20k+ 行代码,它们自始至终都使用 CStrings。我宁愿用 C# 重写应用程序。
  • @KevinDiTraglia 呵呵,哎呀,原来如此:)
【解决方案2】:

来自 MSDN:

errno_t strcpy_s(
   char *strDestination,
   size_t numberOfElements,
   const char *strSource 
);

在这里,在您的代码中,您在一个未初始化的数组上调用 strlen,您需要修复它(传递目标缓冲区可以存储的最大元素数):

strcpy_s( psz2, strlen(psz2), (const char *) *pstr );

【讨论】:

  • 你不是只是复制了错误以将 strlen(psz2) 作为长度参数传递给 strcpy_s() 吗?
  • 是的,我在这里显示了与错误的确切一致,而不是显示错误修复(留给读者作为练习 - 应该很容易,真的)。
猜你喜欢
  • 1970-01-01
  • 2010-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-04
  • 2021-06-16
相关资源
最近更新 更多