在释放动态内存时,Visual Studio中的堆损坏错误

时间:2016-01-29 20:22:23

标签: c++ visual-studio-2012 dynamic-arrays

我遇到了一个将数字连接到char数组末尾的函数的问题。老实说,我无法看到这个问题:

void x(int num, char* originalArray) {

    char* concat_str = new char[1];
    sprintf(concat_str, "%d", num);

    for (int i = 0; i < 1; i++)
        originalArray[i + 10] = concat_str[i];

    delete [] concat_str;
   }

错误消息是:

  

HEAP CORRUPTION DETECTED:在正常块(#147)之后的0x01204CA0。 CRT检测到应用程序在堆缓冲区结束后写入内存。

有什么想法吗?我是一名初学程序员,但我多次做过同样的事情并且从未遇到过这个问题。感谢。

3 个答案:

答案 0 :(得分:4)

concat_str需要足够大才能保存num中的位数加上空终止符。因为它的大小是1,所以你只有空终止符的空间。尝试添加任何其他内容是未定义的行为,因为它访问您不拥有的内存并导致堆损坏。

答案 1 :(得分:1)

你为concat_str分配了一个字节,而sprintf需要更多的空间。

答案 2 :(得分:1)

首先,请注意您的API是C api。如果您想在C ++中使用动态数组,请使用std::vector<char>

但是,假设您需要坚持使用C API,那么就无法保证originalArray足够大以保存结果。此外,临时缓冲区是不必要的。

您应该修改API和实现,如下所示:

  1. 取目的地的大小,以保证它不会写到目的地。

  2. 将字符串写入目标缓冲区中。将它放入临时缓冲区,然后复制到目的地是浪费时间。

  3. 使用snprintf,而不是sprintf。后者是不安全的:你不能保证它不会写到缓冲区的末尾。

  4. 您应该断言偏移量至少小于目标大小的前提条件。

    如果前置条件成立,则目标将始终正确地以零终止,尽管num的文本表示可能不适合。

  5. 您可以返回值适合的目的地长度。

  6. 因此:

    size_t fun(int num, char * dest, size_t dest_size) {
      const size_t offset = 10;
      assert(dest_size > offset);
      return offset + snprintf(dest + offset, dest_size - offset, "%d", num);
    }