C++ 删除C++;指针
好吧,这让我很困惑。我正在处理一些遗留的C++代码部分,我有一种感觉是不安全的,但我不是100%肯定。这里有一个片段,例如,关于风险的东西C++ 删除C++;指针,c++,pointers,struct,new-operator,delete-operator,C++,Pointers,Struct,New Operator,Delete Operator,好吧,这让我很困惑。我正在处理一些遗留的C++代码部分,我有一种感觉是不安全的,但我不是100%肯定。这里有一个片段,例如,关于风险的东西 struct A { A() : a_ptr(0) {} A(some_type *ptr) : a_ptr(ptr) {} const some_type *a_ptr; }; struct B { B() : b_ptr(0) {} B(some_type *ptr) : b_ptr(ptr) {} co
struct A {
A() : a_ptr(0) {}
A(some_type *ptr) : a_ptr(ptr) {}
const some_type *a_ptr;
};
struct B {
B() : b_ptr(0) {}
B(some_type *ptr) : b_ptr(ptr) {}
const some_type *b_ptr;
};
struct Data {
Data(...) {//-Stuff that doesn't invole aptr_list or bptr_list;
}
~Data() {
for(std::vector<A*>::iterator itr = aptr_list.begin(); itr != aptr_list.end() ++itr) {
delete *itr;
}
for(std::vector<B*>::iterator itr = bptr_list.begin(); itr != bptr_list.end() ++itr) {
delete *itr;
}
}
std::vector<A*> aptr_list;
std::vector<B*> bptr_list;
private:
Data(const Data&);
Data& operator=(const Data&);
};
结构A{
A():A_ptr(0){}
A(某些类型*ptr):A_ptr(ptr){}
const some_type*a_ptr;
};
结构B{
B():B_ptr(0){}
B(某些类型*ptr):B_-ptr(ptr){}
const some_type*b_ptr;
};
结构数据{
数据(…){/-不包括aptr_列表或bptr_列表的内容;
}
~Data(){
对于(std::vector::iterator itr=aptr_list.begin();itr!=aptr_list.end()++itr){
删除*itr;
}
对于(std::vector::iterator itr=bptr_list.begin();itr!=bptr_list.end()++itr){
删除*itr;
}
}
std::向量aptr_列表;
std::矢量bptr_列表;
私人:
数据(常数数据&);
数据和运算符=(常量数据和);
};
在实施过程中,我发现:
void some_func(...) {
//-Inside some function
Data& d = get_data(...);
...
for(...) {
some_type *sptr = dynamic_cast<some_type*>(a_source_of_some_type_pointer);
A* a = new A(sptr);
B* b = new B(sptr);
d.aptr_list.push_back(a);
d.bptr_list.push_back(b);
}
}
void一些函数(…){
//-在某些函数中
Data&d=获取数据(…);
...
对于(…){
some_type*sptr=dynamic_cast(some_type_指针的_源_);
A*A=新的A(sptr);
B*B=新的B(sptr);
d、 aptr_列表。推回(a);
d、 bptr_列表。推回(b);
}
}
我对上面的实现中使用的同一个指针sptr
感到有点不安;当调用数据
的析构函数时,这会产生问题吗?另一方面,看起来我们有两个new
调用A*
和B*
并且正好有两个delete
s,所以如果数据中的析构函数不深-也许这就是我需要澄清的地方,那么也许这毕竟是安全的,我的担心是错的?我确实注意到结构A
和B
没有定义任何析构函数,所以我希望它不是很深。但我不确定这是否意味着它们的指针数据将被释放。一如既往地欣赏专家的见解
感谢您的时间和关注。sptr
不属于A或B,因此这是正确的。sptr
不属于A或B,因此这是正确的。A和B
没有用户定义的析构函数,因此A
或B
中的任何内容都不会被销毁(除了它所持有的实际内存被释放之外,但是由于sptr
只是被保存在那里,它没有被删除)。[显然,如果A
或B
包含其他类,比如std::string
或std::vector
,该类将被销毁]
因此,换句话说,您的代码就像-a
和b
一样,只保存了一份sptr
,但它永远不会被删除[在这段代码中,如果以后需要删除,那是另一回事].A
和B
没有用户定义的析构函数,因此A
或B
中的任何内容都不会被破坏(除了它所保存的实际内存被释放外,但由于sptr
只是保存在那里,所以它不会被删除
)。[显然,如果A
或B
包含其他类,例如std::string
或std::vector
,则该类将被销毁]
因此,换句话说,你的代码就像它一样-a
和b
只保存sptr
的一个副本,但它永远不会被删除[在这段代码中,如果以后需要删除,那是另一回事]。数据:~Data()
不会破坏sptr
指针。它将调用a:~a()
和B::~B()
仅限
我不知道你想做什么,但是如果你想进行深度破坏,你需要确保你没有释放一个以前已经被人释放的内存地址
这取决于实现要求,但理想情况下分配对象的用户也应该释放。因此,由于此sptr
是由其他人分配的,如果释放它,您可能会得到一个悬空指针。数据::~Data()
不会破坏sptr
指针。它将调用a:~a()
和B::~B()
仅限
我不知道你想做什么,但是如果你想进行深度破坏,你需要确保你没有释放一个以前已经被人释放的内存地址
这取决于实现要求,但理想情况下,分配对象的用户也应该释放。因此,由于此sptr
是由其他人分配的,如果释放它,您可能会得到一个悬空的指针。如果我们真的很挑剔,那么代码可能会泄漏
如果d.aptr\u list.push\u back()
需要并未能保留更多容量,则a
和b
指向的内存将泄漏
for(...) {
some_type *sptr = dynamic_cast<some_type*>(a_source_of_some_type_pointer);
A* a = new A(sptr); // Allocate memory
B* b = new B(sptr) // Allocate memory (and missing semicolon!!)
d.aptr_list.push_back(a); // If this fails,
d.bptr_list.push_back(b); // or this,
} // then exception is thrown and memory is lost
// (unless you catch the exception and
// perform a delete).
如果我们真的很财务,那么代码可能会泄漏
如果d.aptr\u list.push\u back()
需要并未能保留更多容量,则a
和b
指向的内存将泄漏
for(...) {
some_type *sptr = dynamic_cast<some_type*>(a_source_of_some_type_pointer);
A* a = new A(sptr); // Allocate memory
B* b = new B(sptr) // Allocate memory (and missing semicolon!!)
d.aptr_list.push_back(a); // If this fails,
d.bptr_list.push_back(b); // or this,
} // then exception is thrown and memory is lost
// (unless you catch the exception and
// perform a delete).
只要*sptr
的生命周期包含B
和B
使用它的对象的生命周期。确实,但问题是关于数据调用::~Data。只要*sptr
的生命周期包含B
和B
使用它的对象的生命周期。确实,但问题是关于数据调用::~Data.st::vector
。问题已解决。此外,如果需要不同的语义,std::shared\u ptr
。此外,运行valgrind以确定是否存在任何语义leaks@EdS:shared\u ptr
看起来确实是个好主意。B*B=new B(sptr)
此行缺少分号。st::vector
。问题已解决。另外,std::shared\u ptr
如果需要不同的语义。另外,运行val