我不知道如何在C ++的幕后实际实现“删除”操作符。例如:
class Node{
int i;
Node *left,*right;
};
int main() {
Node* a = new Node; // somehow the object 'a' is initialised with its data members
delete a;
}
delete a;
在幕后究竟做了什么?就像是
有任何默认的析构函数调用或什么?此外,由于a
包含左右指针,对象a->left
和a->right
是否也被删除了?
核心机器级别会发生什么?
答案 0 :(得分:0)
它没有被标准定义,所以这个问题无法真正解答,因为标准库的多个实现可以随意实现这些东西。
不,*left
和*right
不会被删除(也就是说它不会像delete left
那样做,它只会从内存中删除它们)。就像new Node
没有分配额外的内存来设置*left
/ *right
一样。
您尚未明确定义ctor或dtor,因此不会发生任何特殊情况。但是,如果您将定义构造函数/析构函数,那么new
& delete
。
//编辑:Ofc他们现在被调用,没有用户定义的ctor / dtor,但是没有对你做任何有用的事情。
答案 1 :(得分:0)
当对象的范围结束时,c ++调用默认的析构函数
删除的目的是返回内存(即释放内存),以便计算机可以使用
基本上,当你在运行时使用新或其他东西分配内存时,你有责任在任务完成后释放内存 如果您没有释放内存并且指针/对象死亡,那么您使用的内存将被浪费,并且计算机无法使用该内存,这称为内存泄漏。
如果您因内存泄漏而丢失了太多内存,那么堆/免费存储将没有足够的内存来运行您的操作系统,最终您将不得不重启系统
答案 2 :(得分:0)
delete a;
在幕后究竟做了什么?
可能只是转到存储a
指向的对象的免费商店的位置,并将内存标记为可用于将来的分配。 或许如果您已经告诉编译器创建一个可调试的程序版本,那么内存会被额外清零或以其他方式被篡改。
无论编译器做什么,唯一的保证效果是后续delete a
或尝试取消引用a
会导致未定义的行为。
C ++定义了一种语言,而不是一种实现。
应用 as-if规则,可能根本没有任何事情发生,因为编译器优化已经表明不需要这段代码来创建程序所需的可观察行为。
就像是否有任何默认的析构函数被调用或者是什么?
如果你不编写析构函数,那么编译器会自动插入一个public
。
另外,由于
a
包含left
和right
指针,对象a->left
和a->right
是否也被删除?
小心你的措辞。 a->left
和a->right
是两个对象,就像a->i
一样。 C ++比某些其他编程语言更加宽松地使用“对象”这个词。
删除所有三个对象,是的。但是,a->left
和a->right
每个可能会或可能不会指向其他Node
个对象。其他Node
个对象不会被删除。
毕竟,他们为什么要这样做?谁说这两个Node
个对象只是a->left
和a->right
指向的?考虑一下:
struct Node{
int i;
Node *left,*right;
};
int main() {
Node* a = new Node;
Node l;
Node r;
a->left = &l;
a->right = &r;
delete a;
}
如果delete
以传递方式工作,那么您的代码将尝试删除甚至没有在免费商店中分配的本地对象l
和r
;这将是一场未定义行为的灾难。
核心机器级别会发生什么?
C ++没有说明核心机器级别会发生什么。