我有个问题我不知道怎么解决..。
我们有通用对象池。当请求对象时,池将返回QSharedPointer到第一个可用实例,并指定了自定义Deleter。当QSharedPointer实例引用计数为0时,删除器只将对象返回到池。对于普通的对象来说,一切都很好。当在Qt 5中编译时,它对QObject后继者也很好。
但是,如果在QT4.6中编译-问题就开始了:当第二次请求同一个对象时-应用程序退出时会出现错误:
"QSharedPointer:指针xxx已经有引用计数“
我写了一个简单的测试:
QObject* obj = new QObject();
QSharedPointer<QObject> p(obj, deleter); // deleter here does nothing
p.clear();
QSharedPointer<QObject> p2(obj, deleter); // this crashes the app当在QT4.6中编译时,这肯定会失败。同样:在QT5.x中可以很好地工作。
查看Qt源代码,它发现,当使用这个QObject作为QSharedPointer参数时,4.6会在QSharedPointer中初始化内部参考计数器。这样做是为了确保没有两个智能指针可以指向同一个对象,并且它只能在析构函数中被重置。
当Qt5实例被包装到智能指针中时,QObject不检查ref计数器值,因此它可以工作。
有人知道更旧的Qt版本的解决方法吗?是否有任何方法可以完全重置内部Qt状态,包括ref计数器?任何暗示都是非常欢迎的。
发布于 2014-08-11 18:08:15
假设您有池以避免内存分配和去分配,您应该只分配一次内存,然后在请求并返回“新”对象时显式调用构造函数和析构函数。
/* deleter calls destructor explicitly when return object to pool */
void deleter(QObject *object) {
object->~QObject();
mark_as_available();
}
/* allocate (one object) pool memory without calling constructor*/
QObject *object = ::operator new(sizeof(QObject));
/* request object - calling constructor on already allocated memory */
mark_as_taken();
return QSharedPointer(::new (object) QObject, &deleter);
/* deallocate pool memory without calling destructor */
::operator delete(object);发布于 2018-11-04 12:50:44
只允许一次从QSharedPointer创建QObject,后者则需要复制现有的QSharedPointer实例。
根据Qt 4 和5文档:
当指针超出作用域时,QSharedPointer 将删除它所持有的指针,条件是没有其他QSharedPointer对象引用它。
因此,您的样本行为如下:
QObject* obj = new QObject();
QSharedPointer<QObject> p(obj, deleter); // deleter here does attach to "obj"
p.clear(); //this does cause delete of "obj"
QSharedPointer<QObject> p2(obj, deleter); // using deleted pointer will cause crash (if you are lucky XD)使用QWeakPointer不会删除QObject和断言:
"QSharedPointer:指针xxx已经有引用计数“
是为了确保您不会意外地创建多个删除器(这确实安全了我的一天,我使用的是QSharedPointer,意思是QWeakPointer),但它有时会妨碍您。
https://stackoverflow.com/questions/24522600
复制相似问题