我用一个名为cmysqldb的类创建了一个带有大量指针的头文件。 我现在的问题是:
我怎样才能创建一个析构函数来删除可能导致潜在内存泄漏的指针?
这是标题代码:
#ifndef CMSYQLDB_H
#define CMSYQLDB_H
#include <QMultiMap>
#include <QStringList>
#include "mysql.h"
class cmysqldb
{
public:
cmysqldb::~cmysqldb()
{
const char *text,
MYSQL *connection,
MYSQL_RES *result,
MYSQL_RES *fresult,
MYSQL_FIELD *mfield
}
int query_state;
int numfields;
MYSQL mysql;
MYSQL_ROW row;
MYSQL_ROW fieldrow;
....
};
#endif // CMSYQLDB_H
这就是你的意思???
答案 0 :(得分:2)
通过new
获取的资源应使用delete
取消分配,new[]
应使用delete[]
取消分配。就像那样简单,以避免内存泄漏。如果您发布更具体的代码,可能会更有帮助。
析构函数与该类的名称相同,只是它前面有一个~
符号。
cmysqldb :: ~cmysqldb()
{
// deallocate the resources with the above mentioned rule
}
class foo
{
int var ;
int *ptr ;
public:
foo()
{
ptr = new int ;
}
~foo()
{
delete ptr ;
}
};
void bar()
{
foo obj ;
// .....
} // <-- obj goes out of scope and it's destructor is called at this point.
foo
类分别有两个类型为var, ptr
的成员变量int, int*
。因此,自动分配保存var
中的整数和指向整数地址的指针(ptr
)所需的字节数。这些资源不是我们分配的。因此,解除这些资源并不是我们的责任。到现在为止还挺好。
ptr = new int ;
new int
从免费商店获取可以容纳int
的资源,并返回ptr
所持有的地址。现在,从免费商店获取资源是因为用户定义的new
操作。因此,用户的工作是将资源返回到免费商店。那么,析构函数中的语句 -
delete ptr ;
从The Definitive C++ Book Guide and List获取一本甚至可以更好地解释的书。另请遵循@Michael关于使用自动管理资源的智能指针的建议。
答案 1 :(得分:2)
为了删除指针,您需要将它们存储在某处。目前还不清楚你在哪里这样做(你没有构造函数接受的所有指针参数的字段),所以我将无法准确地给出你这样做的代码,但我会说明你怎么做去做这个......
要声明析构函数,请将以下内容添加到类声明中:
~cmysqldb();
请注意,如果您的类具有任何虚拟方法,则应将其声明为:
virtual ~cmysqldb();
在源文件中添加:
cmysqldb::~cmysqldb()
{
// contents of your destructor goes here.
}
现在,您如何释放资源取决于他们的分配方式。如果你使用了一些特定于库的创建函数,并且有一个特定于库的自由函数,那么就使用它。如果是使用malloc分配的,则使用free;如果分配了新,请使用删除;如果是使用 new [] 分配的,则使用删除[] 。此外,您应该尽可能使用智能指针类,如boost::scoped_ptr(std :: unique_ptr)或boost::shared_ptr(std :: shared_ptr),以避免在构造函数中通过new / delete显式管理这些资源/析构函数。
最后,非常重要的一点......每当你有一个接受指针的函数时,记录所有权语义是非常重要的。它是由呼叫者拥有的吗?所有权转移?等
答案 2 :(得分:0)
使用new
或new[]
&amp;获取动态内存时发生内存泄漏不要使用delete
或删除[]`来释放内存。
您的构造函数声明的类型为:
cmysqldb(const char *text, MYSQL *connection, MYSQL_RES *result,
MYSQL_RES *fresult, MYSQL_FIELD *mfield);
您应该使用new
和new[]
跟踪构建器中正在执行的动态内存分配,并且应该使用相应的delete
或{{1}释放所有动态内存分配}}
答案 3 :(得分:0)
最好的办法是使用智能指针存储指向相关对象的所有指针。当父对象被销毁时,C ++将自动调用所有子对象的析构函数。
如果您的父对象部分构造失败,则不会调用其析构函数。因此,如果您设计要在析构函数中释放的内容,那么已分配的任何指针都会泄漏。但是,如果子对象被分配,则子对象析构函数会运行,因此通过使用智能指针,可以为您处理这个部分分配的案例。
有关更多信息,请查找RAII(资源获取是初始化)。