您正在分配单个字符而不是数组。利用:
char* ptr;
ptr=new char[65];
strcpy(ptr,"asdf");
delete[] ptr;
就像现在一样,您将第一个写入a
分配的字符,其余写入一些从未分配给您的任意内存。运行时检测到(在调试版本中)并抱怨。
对我的答案的问题部分发表评论:
C++ 没有任何机制来识别问题代码中的潜在错误。编译器知道传递给的缓冲区大小的唯一方法strcpy
是使用静态分析,这可能有效,也可能无效。但即使是这样,编译器也不知道strcpy
. 所以在编译时,它不能警告你这个错误。
现在,当缓冲区strcpy
在运行时传递给时,strcpy
无法判断该缓冲区有多大。所以它只是假设调用者提供了一个合适的缓冲区,然后继续复制。如果幸运的话,由于对未分配页面的写入,溢出分配的缓冲区将导致立即崩溃。如果没有,你会得到一个内存损坏。
您确实得到的错误是调试构建中使用的机制的结果:内存管理器分配的字节数比您要求的多一些,并将特殊模式写入它们。然后,当分配的内存被释放时,它会检查该模式是否仍然存在。如果没有,它会抱怨用户的代码已写入它们。在发布版本中,您没有那些额外的检查,并且此类错误可能会导致损坏而不会被注意到。
避免这种情况的唯一方法是编写更安全的代码:
- 使用更高级别的构造,例如
std::string
. 他们为您进行内存管理,使您不必处理低级字符串函数。
- 例如,使用 Microsoft 的(非标准)安全变体 - strcpy_s。这些函数也会占用缓冲区的大小,如果不足则失败 - 不会造成任何损害。
- 使用(标准)strncpy,将缓冲区的大小作为最后一个参数传递,并检查返回值以查看已复制了多少字符。与前面的建议一样,指定错误的缓冲区大小仍然会造成损坏。
- 请记住,如果您想自己动手,C++ 会很乐意给您一把指向下方的枪。必须小心处理原始缓冲区、指针和低级字符串函数。语言不会把你从自己的错误中拯救出来。