垫子没有被正确销毁

  • 本文关键字: c# emgucv
  • 更新时间 :
  • 英文 :


在我用C#编写的软件中,我实现了一个用于内部目的的映像类。在那节课上,我拿着emgu CV的Mat

class MyOwnImage : IDisposable
{
private Mat mat;
public MyOwnImage( Mat mat ) {
this.mat = mat;
}
public void Dispose() {
mat.Dispose();
}
//...
}

现在,我发现,无论我是否在Image对象上调用Dispose(),我的内存使用量都在不断增长。我仔细查看了Mat类,发现它内部以IntPtr的形式存在未被否定的内存。因此,我尝试了一下,如果手动释放指针会有所不同:

class MyOwnImage : IDisposable
{
private Mat mat;
public MyOwnImage( Mat mat ) {
this.mat = mat;
}
public void Dispose() {
Marshal.FreeHGlobal( mat.DataPointer ); // data pointer is the IntPtr
mat.Dispose();
}
//...
}

我有点惊讶,但它解决了内存溢出的问题。因此,我假设我必须手动销毁Mat对象中的数据。之后,如果有人忘记手动Dispose()图像,我试图通过添加析构函数来使其更加稳定。

class MyOwnImage : IDisposable
{
private Mat mat;
public MyOwnImage( Mat mat ) {
this.mat = mat;
}
~MyOwnImage() {
destroy();
}
private void destroy() {
Marshal.FreeHGlobal( mat.DataPointer ); // data pointer is the IntPtr
mat.Dispose();
}
public void Dispose() {
destroy();
}
//...
}

不幸的是,这变成了一个新问题:当调用destructor时,Mat对象似乎已经被破坏了。接下来,在调用FreeHGlobal(...)的线路上抛出一个AccessViolationExcetion。现在,我进行了另一个测试,并删除了Dispose()函数中的destroy()调用。

class MyOwnImage : IDisposable
{
private Mat mat;
public MyOwnImage( Mat mat ) {
this.mat = mat;
}
~MyOwnImage() {
destroy();
}
private void destroy() {
Marshal.FreeHGlobal( mat.DataPointer ); // data pointer is the IntPtr
mat.Dispose();
}
public void Dispose() {
//destroy();
}
//...
}

奇怪的是,这并没有改变这样一个事实,即当调用析构函数~MyOwnImage时,MyOwnImage中的mat似乎已经不见了。

最后,我想知道几件事:

  1. 如果我手动调用Dispose(),那么以后也会调用析构函数吗
  2. MyOwnImage的内部对象是否可能在调用此类的析构函数之前被销毁
  3. 如果有OpenCV专家:处理垫子是否可能无法释放里面的数据?如果是,这是一个错误还是有原因

J在评论中指出了这个问题。

违反了所有权模式。正如他所建议的,我在MyOwnImage中克隆了Mat对象,现在它正在工作。

class MyOwnImage : IDisposable
{
private Mat mat;
public MyOwnImage( Mat passedMat ) {
var copy = new Mat();
passedMat.CopyTo( copy );
mat = copy;
}
public void Dispose() {
mat.Dispose();
}
//...
}

相关内容

  • 没有找到相关文章

最新更新