关于删除C++指针
On deleting C++ pointers
好的。。所以这让我很困惑。我正在处理一些遗留的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) {}
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&);
};
然后在实现中,我发现:
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);
}
}
我对在上面的实现中使用相同的指针sptr
感到有点不安;当调用Data
的析构函数时,这会产生问题吗?另一方面,看起来我们对A*
和B*
有两个new
调用,正好有两个delete
,所以如果Data
中的析构函数不深——也许这就是我需要澄清的地方,那么也许这毕竟是安全的,我的担忧是错的?我确实注意到,例如,结构A
和B
没有定义任何析构函数,所以我希望它不深入。但我不确定这是否意味着他们的指针数据会被释放。一如既往地欣赏专家的真知灼见。
感谢您的时间和兴趣。
A
和B
没有用户定义的析构函数,因此a
或b
内部的任何东西都不会被破坏(除了它所包含的实际内存被释放之外,但由于sptr
只是被保存在那里,所以它不是deleted
)。[显然,如果A
或B
包含其他类,例如std::string
或std::vector
,则该类将被销毁]。
所以,换句话说,你的代码就是这样——a
和b
只保存了sptr
的一个副本,但它从未被删除[在这段代码中,如果以后需要删除,那就另当别论了]。
Data::~Data()
不会破坏sptr
指针。它将只调用A::~A()
和B::~B()
。
我不确定你想做什么,但如果你想进行深度破坏,你需要确保你不会释放之前已经被某人释放的内存地址。
这取决于实现需求,但理想情况下,分配对象的用户也应该释放。因此,由于这个sptr
是由其他人分配的,如果你释放它,你可能会得到一个悬空的指针。
sptr
不归A或B所有,因此这是正确的。
如果我们真的很挑剔,那么代码可能会泄漏。
如果d.aptr_list.push_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).
为了安全起见,应该使用像std::unique_ptr
这样的智能指针来包裹指针。
您的列表类型应为std::vector<std::unique_ptr<A>>
和std::vector<std::unique_ptr<B>>
。
在some_func
中,代码可以读取如下内容:
some_type *sptr = dynamic_cast<some_type*>(a_source_of_some_type_pointer);
d.aptr_list.push_back(std::unique_ptr<A>(new A(sptr)));
d.bptr_list.push_back(std::unique_ptr<B>(new B(sptr)));
- 1d 智能指针不适用于语法 (*)++
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 为什么使用 "this" 指针调用派生成员函数?
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用指针从C++中的数组中获取最大值
- 助记符和指向成员语法的指针
- 嵌入方指针压缩已禁用
- 数组的指针从不分段故障
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 何时在引用或唯一指针上使用移动语义
- QMetaObject invokeMethod的基于函数指针的语法
- 如何从 std::atomic 中提取指针 T<T>?
- 如何在 C# 中映射双 C 结构指针?
- C++将浮点指针值舍入为小数位数
- 为什么++(*p)更改指针值
- 调整大小后指向元素值的指针unordered_map有效?
- 正在将指针转换为范围
- 使用指向成员的指针将成员函数作为参数传递
- 将OpenCV C++重写为EmguCV C#-如何使用指针
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错