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

Heap corruption error in Visual Studio while freeing dynamic memory

我在使用将数字连接到 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: after Normal block (#147) at 0x01204CA0. CRT detected that the application wrote to the memory after the end of heap buffer.

有什么想法吗?我是一个新手程序员,但我做过很多次同样的事情,从来没有遇到过这个问题。谢谢

您正在为 concat_str 分配一个字节,然后 sprintf'ing 需要更多 space 的内容。

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

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

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

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

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

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

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

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

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

  5. 您可以 return 值适合所需的目的地长度。

因此:

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);
}