我无法理解如何删除对象并将指针设置为null。
例如:
Class* c = new Class();
我们可以将指针设置为null
c=null;
在这种情况下,对象仍然在内存中,并没有任何指向它。我们将如何删除它?
或
delete c;
在这种情况下我们删除一个对象,但指针仍然指向前一个对象的地址位置。在哪些情况下可能有用?
答案 0 :(得分:2)
要解除分配new
分配的对象,您应该使用delete
。
要防止指针变为"dangling",请将指针设置为nullptr
。
Class* c = new Class();
delete c; // free up the allocated memory from new
c = nullptr; // prevent dangling pointer
如果在销毁后不再使用c
,则不需要将其分配给nullptr
。
nullptr
之后指针设置为delete
的原因是因为像
if (c != nullptr) {
delete c;
c = nullptr;
}
这是冗余,因为delete
已经检查指针是否仍然指向有效的内存位置。
如果已经nullptr
,那么它什么都不做。
否则,delete-expression不会调用deallocation 功能
[注意:不管是什么,都会调用释放函数 是对象的析构函数还是数组的某个元素 抛出一个例外。 - 结束注释]如果操作数的值 delete-expression是空指针值,它是未指定是否是 如上所述,将调用释放函数。
答案 1 :(得分:2)
[设置c = null后]对象仍在内存中,没有任何内容指向它。怎么样 我们要删除它吗?
你不能 - 在这种情况下你的程序有一种叫做memory leak
的bug,因为如果没有指向对象的指针,你就无法删除你分配的对象。如果您不希望程序的内存使用量随着时间的推移而增长(并且可能在某些时候耗尽其主机的内存),保留至少一个指针是非常重要的。您动态分配的每个对象,这样您就可以在使用它时保留delete
对象的功能。
[在另一种情况下]我们删除一个对象,但指针仍然指向地址 上一个对象的位置。在哪些情况下可能有用?
指向已删除对象的指针几乎从未有用 - 尝试取消引用指针将导致undefined behavior
,技术上甚至读取悬空指针的值(不解除引用它)是禁止的好(!)。不将指针设置为NULL的唯一原因是因为将指针设置为NULL将需要额外的CPU指令(以及额外的写入内存)才能执行,并且C ++尝试不会强迫您支付您不需要的开销。 ;需要付钱。所以如果你能保证你永远不会尝试使用"悬空指针"删除对象后,将其设置为NULL的效率要比将其设置为NULL的效率要高一些。
如果上述所有内容对您来说都是程序员不友好,那么您绝对正确 - 事实如此。原始指针需要程序员非常严格的行为,如果程序员没有正确处理它们,结果就是一个错误的程序(内存泄漏,或运行时崩溃,或其他未定义但不良行为)。如果您更愿意避免这种风险(并且您应该!)然后使用原始指针(例如Class *
)而不是保持动态分配的对象,您可以使用&#34保持它;智能指针"例如std::unique_ptr
或std::shared_ptr
。智能指针类将为您提供"它自动做正确的事情"原始指针所没有的行为,代价是为您的程序增加了微不足道的开销。
答案 2 :(得分:-1)
在将其设置为delete
之前,您应该nullptr
指针。但如果您不再使用它,则无需将其设置为nullptr
。在这种情况下,让指针悬空(指无效的内存块)就可以了。
但我总是更喜欢RAII,它表示在构造函数中分配资源并在析构函数中释放它。它减少了指针的使用。然后,您不需要使用指针来创建对象的实例。当然,这并不总是实用,但这是一个很好的做法。
// RAII implementation
class ClassA
{
char *buffer;
public:
ClassA(): buffer(new buffer[1000])
{
}
~ClassA()
{
delete buffer;
// now *buffer is invalid (dangling pointer) but it is easy to
// rely that this invalid code is not called anymore.
}
}
...
int main()
{
ClassA instance;
// here you do not need to use a pointer.
}