释放动态内存时 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 和实现如下:
获取目的地的大小,以保证它不会写到最后。
将字符串写入目标缓冲区中的适当位置。把它放到一个临时缓冲区,然后复制到目的地是浪费时间。
使用 snprintf
,而不是 sprintf
。后者是不安全的:你不能保证它不会写超过你的缓冲区的末尾。
您应该断言偏移量至少小于目标大小的前提条件。
如果前提条件成立,目标将始终正确地以零终止,尽管 num
的文本表示可能不适合它。
您可以 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);
}
我在使用将数字连接到 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 和实现如下:
获取目的地的大小,以保证它不会写到最后。
将字符串写入目标缓冲区中的适当位置。把它放到一个临时缓冲区,然后复制到目的地是浪费时间。
使用
snprintf
,而不是sprintf
。后者是不安全的:你不能保证它不会写超过你的缓冲区的末尾。您应该断言偏移量至少小于目标大小的前提条件。
如果前提条件成立,目标将始终正确地以零终止,尽管
num
的文本表示可能不适合它。您可以 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);
}