正常阻塞后检测到堆损坏(#174)

时间:2013-03-01 07:22:07

标签: c++ char swap heap-corruption

我知道这个问题已被问到我无法修复我的程序

  void swap1(char*str1,char*str2)
{
    char *ezer =new char[strlen(str1)];
    for (int i = 0 ; i <= strlen(str1);i++)
        ezer[i]=str1[i];
    delete [] str1;
    str1= new char[strlen(str2)];
    for (int i = 0 ; i <= strlen(str2);i++)
        str1[i]=str2[i];
    delete [] str2;
    str2= new char[strlen(ezer)];
    for (int i = 0 ; i <= strlen(ezer);i++)
        str2[i]=ezer[i];
    delete[] ezer;
}

一次第一次它的工作蝙蝠在第二次(有其他值)时间我得到一个错误 错误来自最后一行delete[] ezer;为什么我无法删除ezer

错误:

heap corruption detected after normal block (#174) at 0x007D7A48
CRT detected that the application wrote to memory end of heap buffer

2 个答案:

答案 0 :(得分:5)

strlen不计算字符串末尾的null终止符。这意味着在交换函数的一次应用之后,将交换两个字符串,但不再为null终止。 strlen在没有空终止符的字符串上的行为是未定义的,这意味着当您遍历其中一个被删除的字符串时,您正在分配堆的边界之外运行。

C中的字符串表示为一个字符指针,其零值字节表示字符串的结尾(我提到的空终止符)。任何对“字符串”进行操作的库例程都需要提供一个字符数组,其末尾标记为null,否则将具有未定义的行为(因为您将提供一个char数组,而不是此时的字符串)。

使用库函数strcpy而不是自己滚动。

有关详细信息,请参阅this question

答案 1 :(得分:0)

你错过了在这里为0终结者分配空间:

char *ezer = new char[strlen(str1)];

将此更改为:

char *ezer = new char[strlen(str1) + 1];

实际的(第一次)内存损坏发生在这里:

  for (int i = 0 ; i <= strlen(str1);i++)
    ezer[i]=str1[i];

与上一次迭代(复制0终结符的那次)ezer[i]一样,引用内存“就在后面”为ezer分配的内容。

对字符arrayc的其他两个分配重做相同。

无论如何,因为这会修复堆损坏,该函数将不会按预期运行。但这是另一个故事......不是吗? ; - )

相关问题