我使用类之间共享的指针在c ++中遇到内存释放问题。
一个例子:
我的顶点定义为:
@Component
public class FtpServer {
@Value("${ftp.port}")
private int port;
@PostConstruct
public void init() {
System.out.println(this.port);
}
}
正方形定义为:
class Vertex{
double x;
double y;
}
我的析构函数实现如下:
class Square{
Square(Vertex* a, Vertex* b, Vertex* c, Vertex* d);
~Square(); // destructor
Vertex* a;
Vertex* b;
Vertex* c;
Vertex* d;
}
我的方块存储在Square::~Square(){
delete a;
delete b;
delete c;
delete d;
}
中,所以为了清理我的所有记忆,我做了:
std::vector<Square*> squares
那么问题是什么?如果两个方格共享一个顶点,我的程序崩溃,因为它试图删除一个不再存在的指针。 我怎么解决这个问题?
答案 0 :(得分:5)
在我看来,你是用C ++编写的,具有类似Java的思维模式。只包含两个Vertex
的{{1}}个对象(例如你的X和Y组件)更好地存储在堆栈中,没有指针间接。所以,我会像这样声明double
类:
Square
如果您想要一种参考机制,而不是嵌入class Square{
...
Vertex a;
Vertex b;
Vertex c;
Vertex d;
};
对象,您可以将顶点存储在Vertex
数组中,并存储在std::vector<Vertex>
类整数中索引到数组中的顶点位置。
如果确实希望使用指针共享所有权语义,请考虑使用智能指针,如Square
。当引用计数达到零时,没有明确的std::shared_ptr
:delete
将自动释放内存。
在这种情况下,将shared_ptr
类中的原始Vertex*
拥有指针数据成员替换为shared_ptr<Vertex>
。此外,从Square
类中删除析构函数代码,因为Square
知道如何删除自身。
在shared_ptr
类构造函数中,您可以按值Square
智能指针,并在相应的数据成员中shared_ptr<Vertex>
,例如:
std::move
还将Square::Square(
std::shared_ptr<Vertex> pa,
std::shared_ptr<Vertex> pb,
std::shared_ptr<Vertex> pc
)
: a{std::move(pa)}
, b{std::move(pb)}
, c{std::move(pc)}
{}
替换为vector<Square*>
(但是,您确定更简单的vector<shared_ptr<Square>>
不能为您提供服务吗?),并使用vector<Square>
创建智能指针。
答案 1 :(得分:2)
除非你有充分的理由这样做,否则你不应该在Modern C ++中手动分配内存。如果您的Square
类要为Vertex
个实例的共享所有权建模,那么您应该使用std::shared_ptr
:
class Square{
// ...
std::shared_ptr<Vertex> a, b, c, d;
}
但是我建议你重新考虑使用动态内存分配来简化和轻量级Vertex
。
答案 2 :(得分:0)
如果您使用遗留代码并且无法将原始指针更改为共享指针,或者您不能简单地复制顶点(您想要引用原始对象),那么不要删除Square析构函数中的顶点,并且可能使用对顶点的引用而不是指针。
您已经在Square对象之外管理Vertexes的分配,因此请确保仅在所有正方形消失后才释放顶点。
代码流程如下所示: