返回信息流请教各位,以下代码中的单例模式,是否有内存泄露的问题?new出来的数据能正确析构吗?
class CSingleton
{
private:
CSingleton() {};
static CSingleton * m_pInstance;
class CGarbo // 它的唯一工作就是在析构函数中删除CSingleton的实例
{
public:
~CGarbo()
{
if (CSingleton::m_pInstance)
{
delete CSingleton::m_pInstance;
}
}
};
public:
static CGarbo Garbo; // 定义一个静态成员,在程序结束时,系统会调用它的析构函数
static CSingleton * instance()
{
if (m_pInstance == NULL)
m_pInstance = new CSingleton();
return m_pInstance;
}
};
CSingleton* CSingleton::m_pInstance = NULL;
CSingleton::CGarbo CSingleton::Garbo;//这一行注释掉也能编译通过,注释了会有什么不同?
int main()
{
CSingleton* ptr=CSingleton::instance();
return 0;
}
这是一条镜像帖。来源:北邮人论坛 / cpp / #88522同步于 2015/9/8
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
【请教】以下的单例模式是否存在内存泄露?
en911
2015/9/8镜像同步14 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
【 在 en911 的大作中提到: 】
: 请教各位,以下代码中的单例模式,是否有内存泄露的问题?new出来的数据能正确析构吗?
: class CSingleton
: {
: ...................
class CSingleton
{
private:
CSingleton() {};
static CSingleton * m_pInstance;
class CGarbo // 它的唯一工作就是在析构函数中删除CSingleton的实例
{
public:
~CGarbo()
{
if (CSingleton::m_pInstance)
{
delete CSingleton::m_pInstance;
}
}
};
public:
/////// declaration instead of definition ///////
static CGarbo Garbo; // 定义一个静态成员,在程序结束时,系统会调用它的析构函数
static CSingleton * instance()
{
if (m_pInstance == NULL)
m_pInstance = new CSingleton();
return m_pInstance;
}
};
CSingleton* CSingleton::m_pInstance = NULL;
////// definition is here //////
CSingleton::CGarbo CSingleton::Garbo;//这一行注释掉也能编译通过,注释了会有什么不同?
int main()
{
CSingleton* ptr=CSingleton::instance();
return 0;
}
without definition, compilation succeeded because nothing need this symbol.
看起来很奇怪的RAII,哎,小菜也不知道有没有泄漏,还是要等楼下大神啊。。。
专注暖场30年
注释掉类外的CSingleton::CGarbo CSingleton::Garbo定义式会存在内存泄漏.其余看解释. 个人理解,欢迎讨论.
class CSingleton
{
private:
CSingleton() {};
static CSingleton * m_pInstance;
class CGarbo // 它的唯一工作就是在析构函数中删除CSingleton的实例
{
public:
~CGarbo()
{
if (CSingleton::m_pInstance)
{
delete CSingleton::m_pInstance;
}
}
};
public:
static CGarbo Garbo; // 定义一个静态成员,在程序结束时,系统会调用它的析构函数
static CSingleton * instance()
{
if (m_pInstance == NULL)
m_pInstance = new CSingleton();
return m_pInstance;
}
};
CSingleton* CSingleton::m_pInstance = NULL;
CSingleton::CGarbo CSingleton::Garbo;//这一行注释掉也能编译通过,注释了会有什么不同?
// 能编译通过是因为程序中没有使用Garbo的地方,
// 所以Garbo只有声明,没有定义. 你可以在任何地方
// 调用一下CSingleton::Garbo,
// 注掉此句肯定链接不通过.
int main()
{
CSingleton* ptr=CSingleton::instance();
return 0;
}
Garbo 不能是普通成员变量,因为程序退出前没有地方调用它的析构函数
【 在 wuxuecheng 的大作中提到: 】
: 注释掉类外的CSingleton::CGarbo CSingleton::Garbo定义式会存在内存泄漏.其余看解释. 个人理解,欢迎讨论.
: class CSingleton
: {
: ...................
恩,想错了,单例必须依靠Garbo先释放,已更正.
【 在 inaadversity 的大作中提到: 】
: Garbo 不能是普通成员变量,因为程序退出前没有地方调用它的析构函数
首先,假设 CSingleton 未初始化,且代码中有两个线程( A 和 B)会调用到 CSingleton::instance()
然后很巧的是,当线程A执行完了 if (m_pInstance == NULL),将要执行下一行去实例化这个单例时,这时切换到了线程B,那么线程B 会去实例化这个单例。而之后切回到了线程A,其也会接着实例化这个“单例”。
在这种情况,线程A和线程B 拿到的是两个不同实例。
所以从线程安全这个角度看,这份代码其实也存在内存泄露的风险。
【 在 en911 的大作中提到: 】
: 请详细说说!
: 来自「北邮人论坛手机版」