我注意到每次我删除二进制搜索树类中的节点时,它只是用0替换它。换句话说,假设我有一个节点树,当按预先遍历遍历打印时“5,3,4,6。”假设我调用remove函数删除3(所有这个函数都是沿树搜索,直到它找到所需的节点,然后在该节点上调用delete)。当我使用预订遍历再次打印时,出现的是“5,0,4,6”。根据我对删除的理解,它释放了所使用的内存,以便指针现在指向任何内容。它不应该只是给出分段错误而不是打印0?
答案 0 :(得分:1)
Delete只调用它所调用的对象的析构函数,并将分配的内存发送回堆。您描述的行为特定于您的实施。
也许你的预订遍历在找到空节点时会打印'0',或者你的析构函数可能存在问题,如果没有看到代码就很难分辨。
答案 1 :(得分:1)
delete
将内存释放回内存管理器,因此,您无法再对所述内存的内容做出任何保证。它可能仍然包含节点的内容,但也可能覆盖了内存。
即使在调用delete之后,你的指针仍然是有效的指针。只是你不能再保证所述内存的内容是有效的。
对于潜在的段错误,如果代码试图取消引用NULL
指针,则代码只会出现段错误。你的指针不是NULL,所以不会发生段错误。
答案 2 :(得分:0)
在C ++编程语言中,delete运算符调用给定参数的析构函数,并将new分配的内存返回给堆“
int * x = NULL;
x = new int(6);
cout << *x << endl;
delete x;
cout << *x;
上面的代码在堆上创建一个int,因为我假设你正在打印它然后将其删除。删除后,x指向的内存返回到开销并分配给某个值,但指针仍然有效。所以上面的代码打印出来:
6 然后是一些随机数
答案 3 :(得分:0)
未定义的行为意味着未定义行为,而不是它应该崩溃。你希望所有未定义的行为快速而艰难地崩溃,但情况并非总是如此。
有多种原因可以解释您所获得的行为,第一个也是最简单的原因是,一般分配器不能处理任何随机大小,而是分配一个小块时可能会出现多个页面与其他分配相同的页面,当您释放它时,它可能不会被返回给操作系统。操作系统可以标记存储页面是可访问的(用于读取,写入或执行),一旦将页面移交给您的应用程序,整个页面可以是可读/可写的。如果取消分配内存,则操作系统中malloc/free
的实现可能不会将内存返回给操作系统,而是将其保留在应用程序中。该内存超出了您的应用范围,但可能没有标记为无法访问。您可以在不崩溃的情况下读取或写入,但不能保证可能发生的事情。
更改运行时配置中的某些参数可能会强制释放内存并导致崩溃,或者内存可能不会被释放,但是用于其他对象并且读取可能不是读取节点,而是任何其他随机对象,写作可能会破坏一些无关代码的状态......