删除已作为函数参数传递的指针(如下所示)是否正常(和合法):
#include<iostream>
class test_class{
public:
test_class():h(9){}
int h;
~test_class(){std::cout<<"deleted";}
};
void delete_test(test_class* pointer_2){
delete pointer_2;
}
int main(){
test_class* pointer_1;
while(true){
pointer_1 = new test_class;
//std::cout<<pointer_1->h;
delete_test(pointer_1);
}
}
现在编译好了,但我只是想确保它一直都是这样。
答案 0 :(得分:12)
它将始终编译而不会出错。
将指针传递给函数并在该函数中删除它是否是件好事可能是另一个故事,具体取决于程序的细节。
您需要考虑的主要想法是指向数据的“所有权”。当你传递那个指针时,调用函数是否拥有传入数据的所有权?即,它是唯一可以引用此数据的地方吗?您是否放弃了指向数据的所有权,而且调用函数不会再次引用数据?如果是这样,那么你必须删除它。
如果调用函数可能再次引用数据,则不能删除它。
如果通过各种数据结构对数据进行其他引用,则删除此数据是不安全的,除非您的代码中有一些规则,以确保您永远不会再从这些地方引用数据。这很难做到,并且是许多编程错误的根源。
C ++ tr1的shared_ptr&lt;&gt;是一种智能指针,有助于在这种情况下 - 它通过保持跟踪数据引用数量的引用计数来管理此所有权概念。如果引用计数为1,则有1个明确的所有者。如果引用计数大于1,则共享所有权。如果引用计数为0,则不再有对数据的引用,并且shared_ptr&lt;&gt;将在shared_ptr&lt;&gt;时将其删除析构函数被称为。
答案 1 :(得分:7)
是的,这是有效的。
这通常在C中完成(显然有malloc和free而不是new和delete)。在C ++中,如果可以的话,通常最好使用其他内存管理习惯用法,例如RAII。
答案 2 :(得分:6)
是的,它在C ++中是合法的,但这样做通常不被认为是一种好的做法。执行new
到delete
的班级总是更好。
答案 3 :(得分:2)
是的,这完全合法。只要指向堆上分配的某个对象(或等于delete
),就可以0
指向任何地方的指针。
调用者是否希望该函数删除其对象,这是另一个问题。
答案 4 :(得分:1)
这是完全合法的,但在这种情况下,用boost::shared_ptr之类的东西管理内存所有权可能会更好。
答案 5 :(得分:0)
这样做是完全合法的。您必须确保在该点之后指针未在调用者中使用。通常,执行删除的函数的名称应指示正在发生的事情(例如,包含删除,释放,免费等)。另一个潜在的问题是确保指向的数据分配了新的而不是新的[]。
答案 6 :(得分:0)
它是有效的,并且在为对象编写清理方法时非常有用,尽管您希望将清理逻辑放入析构函数中9/10次。
虽然编写单独的清理是一个很好的理由,但是如果你想保持对象“活着”但暂时不使用,可能是在你需要一个没有的新对象偶尔拉出的数组或对象池中希望构造函数开销。
如果您要传入指针,则应检查以确保它们不为null以避免任何未定义的行为。
答案 7 :(得分:0)
讨论可能有点晚了,但我想补充一点:该函数仅获取指针的副本( fnc(int* a) 是按值传递),因此您正在删除您传递的指针和原始指针将保持可用。
该代码可能已被编译器优化以避免不必要的分配和删除,从而使其能够正常工作。