如何释放* .dll中分配的内存

时间:2014-08-15 08:15:34

标签: c++ visual-studio-2010 dll memory-leaks

  

我想我需要更清楚地描述我的问题:

     

被调用的dll将仅在堆上管理其内存。呼唤   部分是在堆栈上管理它的内存。呼叫部分没有   访问dll内存分配信息。所以,当我打电话给   解构函数如“~UserVideoAbstration”。它不能释放   在堆上分配的内存。

     

这是与* .dll内部实现相关的问题

我正在做一个项目,有2个部分,一个是将密钥算法实现打包到* .dll文件中。我将算法部分封装到对象实现中。

class UserVideoAbstraction{ 
private:
    VideoAbstraction *userVB;
public:
    __declspec(dllexport) UserVideoAbstraction(const char* inputpath, const char* videoname, const char* midname);
    __declspec(dllexport) UserVideoAbstraction();
    __declspec(dllexport) ~UserVideoAbstraction();

    __declspec(dllexport) void UserAbstraction(Mat& currentFrame, int frameIndex);          //进行背景减除的函数
    __declspec(dllexport) int UsersaveConfigInfo(); 

在构造函数中,我这样写:

UserVideoAbstraction::UserVideoAbstraction(const char* inputpath, const char* videoname,const  char* midname)
{
    string t1=inputpath;
    string t2=videoname;
    string t3=midname;
    userVB =new VideoAbstraction(t1,t2,t3);
}

所以你知道,当我调用* .dll时,它会分配内存。调用部分是项目的第二部分,它是基于.Net的windows实现,但我在第二部分找到,

  

提供这样的解构功能

是没用的
UserVideoAbstraction::~UserVideoAbstraction(){
    delete userVB;
};

所以我想知道你是否有一个很好的解决方案来解决这个问题。


应用程序实现部分介绍......

这是正常的C ++实现,调用部分是一个带有C ++的控件按钮实现(.Net)。

就像那样:

//initial part
UserVideoAbstraction use(inputpath, videoname, midname);

//deconstruct part 
use.~UserVideoAbstration();

3 个答案:

答案 0 :(得分:0)

你应该打电话不要手动调用析构函数。

UserVideoAbstraction::~UserVideoAbstraction(){
    delete userVB;
};

但是,最好使用std::tr1::shared_ptr<VideoAbstraction>而不是原始指针,然后您不必手动删除它。 (您可以在std::shared_ptr<>

中使用C++11

或者根本没有使用[{1}}类型userVB的指针:

VideoAbstraction

答案 1 :(得分:0)

我只是显式定义了一个函数,它执行与解构函数类似的任务来释放对象的内存,分配的内存被成功释放。

这是我的解决方案,第一部分是

void VideoAbstraction::freeObject(){
    videoCapture.~VideoCapture();
    videoWriter.~VideoWriter();
    backgroundImage.release();              
    currentStartIndex.release();
    currentEndIndex.release();
    mog.~BackgroundSubtractorMOG2();
    .............
}

封装部分像那样重新设计

__declspec(dllexport) void UserfreeObject();// declaration part 

//implementation part
void UserVideoAbstraction::UserfreeObject(){
        userVB->freeObject();
}

答案 2 :(得分:0)

从评论看来,您认为问题是由于.NET垃圾收集器没有确定性地删除dll中的C ++对象。这是错的。虽然.NET将使用其构造函数创建对象,但最终将调用析构函数。最终。此时,.NET代码将执行相同的过程,因为调用将发生释放对象使用的内存 - 在此套接字中,该调用将是对象析构函数。

规则很简单:在C ++类中封装所有内容,在构造函数中分配的内容,在解构器中释放。

如果您正在编写C ++ / CLI类,那么您可能希望使用析构函数的endiser语法(叹气,Microsoft ..为什么)uses the ! symbol在类名之前(例如{{} 1}})。如果您正在使用P / Invoke样式互操作,那么现在就停止它,它无论如何都与C ++对象不兼容,并且woudl是你的析构函数没有被自动调用的原因 - 尽管我猜你可以在下面对析构函数进行显式调用你的处置或终结者。