C++ 删除字符数组不会';似乎根本不会影响数组

C++ 删除字符数组不会';似乎根本不会影响数组,c++,char,dynamic-memory-allocation,C++,Char,Dynamic Memory Allocation,所以我执行这个代码 #include <cstdlib> #include <iostream> int main() { char *test = new char[10]; strcpy(test, "Hello Ther");; std::cout << test << std::endl; delete[] test; std::cout << test <<

所以我执行这个代码

#include <cstdlib>
#include <iostream>
int main()
{
    char *test = new char[10];
    strcpy(test, "Hello Ther");;
    std::cout << test << std::endl;
    delete[] test;
    std::cout << test << std::endl;
    return 0;
}
#包括
#包括
int main()
{
字符*测试=新字符[10];
strcpy(test,“Hello Ther”);;

std::cout在
删除[]
数组之后,就没有更多的数组了。之后通过该指针的任何访问都有未定义的行为

delete[]
应该调用数组元素上的析构函数并释放它所使用的存储。由于
char
没有析构函数,它只是释放存储。释放存储仅意味着它不再使用

FWIW,您的代码中还有一个未定义行为的实例。
“Hello Ther”
有11个元素:末尾有一个null(
'\0'
)终止符。
strcpy
将只有10个元素大的元素放入缓冲区是未定义的行为。您需要一个11个元素的缓冲区:“Hello Ther”的10个字符加上空终止符


这类错误,即缓冲区溢出,是安全漏洞的常见来源。至少在20世纪80年代就有著名的利用这类错误的行为。明智的做法是避免此类不安全的原语,并选择安全的现代原语(所谓“现代”,我指的是“从20世纪90年代起”)因为,你知道,这是21世纪。

你期望发生什么


当你删除一个指针时,所有发生的事情就是你调用new时提供给你的内存被返回给系统。如果你在调用delete后没有分配内存或触摸内存(如你的示例所示)内存中的旧内容可能仍然存在。毕竟,如果delete将所有内存归零,则会对性能造成影响(某些编译器的调试版本会在delete上写入特殊值,以便更容易找到无效的内存访问)如果你确实通过分配更多内存或调用函数来触摸内存,那么值可能被破坏。虽然它可能不是,这就是为什么在删除之后访问指针被称为未定义行为的原因。C++中的

< P>可以访问内存是否分配。这触发了未定义的行为,但是没有检查。不管给定的内存是否“可访问”,这都是您的问题。这与基于VM的语言形成对比,后者为您检查内存访问

避免此类错误的一个常见习惯用法是:

delete[] myArray;
myArray = NULL; // preferably "nullptr" in C++11
任何对
NULL
地址的访问都会被CPU拒绝。它会向操作系统发出错误警报(这可能导致程序以segfault或等效错误结束)

正如stonemetal所提到的,一些编译器/操作系统/分配器将在调试构建中检查内存访问,但为了提高速度,不会在发布模式下进行检查


注意:如果您尝试随机访问未分配的内存,您将遇到页面错误,但这有点离题。

您认为
delete[]
应该做什么?算您自己运气好。修复代码中的错误,问题就会消失。(例如,将
delete
移动到最后一次输出之后。)