添加到qstatemmachine的QStates内存管理
Memory management of QStates added to QStateMachine
下面的代码由于内存损坏导致崩溃。我假设这是因为delete pTestStateMachine
试图删除未在堆中分配的内存。对吗?
如果是,这是否意味着QStateMachine::addState(QAbstractState * state)
必须总是传递一个动态分配的内存?不幸的是Qt文档没有指定任何这样的条件。我遗漏了什么?
class CTestClass
{
public:
QState m_pTestState;
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QStateMachine *pTestStateMachine;
CTestClass TestClass;
pTestStateMachine = new QStateMachine();
pTestStateMachine->addState(&(TestClass.m_pTestState));
pTestStateMachine->setInitialState(&(TestClass.m_pTestState));
pTestStateMachine->start();
pTestStateMachine->stop();
delete pTestStateMachine;
return a.exec();
}
是否意味着
QStateMachine::addState(QAbstractState * state)
必须总是传递一个动态分配的内存?
一点也不。QState
在任何方面都不特殊,同样的警告适用于任何QObject
。回想一下,QObject
是其他QObject
的容器:它拥有它们,除非它们首先被单独销毁,否则将尝试在QObject::~QObject
中delete
子对象。
您的代码可以通过几种方式修复-在所有情况下,目标都是不让~QObject
删除它不应该删除的子状态。
如果你让编译器做它应该做的工作,一切都会变得非常简单。您的代码风格是使用原始的拥有指针,而不是在定义点初始化它们,这是不习惯的,并且经常会引发您遇到的错误。如果有归属指针,则使用std::unique_ptr
或QScopedPointer
。delete
和手动内存管理只属于单一用途的资源管理类。它根本不属于通用代码:认为每个显式delete
都是一个bug。你不需要他们。
class CTestClass
{
public:
QState m_pTestState;
};
// Fix 1: Don't mix automatic storage duration with dynamic storage duration
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
{
QStateMachine TestStateMachine;
CTestClass TestClass;
TestStateMachine.addState(&TestClass.m_pTestState);
TestStateMachine.setInitialState(&TestClass.m_pTestState);
TestStateMachine.start();
TestStateMachine.stop();
} // <-- here the compiler emits
// TestClass.~TestClass()
// ...
// TestStateMachine.~QStateMachine()
// ...
// TestStateMachine.~QObject()
}
// Fix 2: Make sure that the child doesn't outlive the parent.
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
{
QScopedPointer<QStateMachine> TestStateMachine(new QStateMachine);
CTestClass TestClass;
TestStateMachine->addState(&TestClass.m_pTestState);
TestStateMachine->setInitialState(&TestClass.m_pTestState);
TestStateMachine->start();
TestStateMachine->stop();
} // <-- here the compiler emits
// TestClass.~TestClass()
// ...
// TestStateMachine.~QScopedPointer()
// delete data;
// data->~QStateMachine
// ...
// data->~QObject
// free(data)
}
从文档的措辞
如果状态已经在另一台机器上,它将首先从旧机器上删除,然后再添加到这台机器上。
QStateMachine
获取QState
的所有权这意味着它会在销毁时删除它拥有的所有状态,你可以传递一个动态分配的指针或者你可以使用QStateMachine::removeState()
从此状态机中删除给定的状态。状态机释放状态的所有权。
所以这应该可以工作:
class CTestClass
{
public:
QState m_pTestState;
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QStateMachine *pTestStateMachine;
CTestClass TestClass;
pTestStateMachine = new QStateMachine();
pTestStateMachine->addState(&(TestClass.m_pTestState));
pTestStateMachine->setInitialState(&(TestClass.m_pTestState));
pTestStateMachine->start();
pTestStateMachine->stop();
pTestStateMachine->removeState(&(TestClass.m_pTestState)); //removing state before deletion
delete pTestStateMachine;
return a.exec();
}
- 当vector是tje全局变量时,c++中vector的内存管理
- 我有一个线程 1:EXC_BAD_ACCESS(代码 = 1,地址 = 0x8)错误.我认为这是由于内存管理不好.我可以
- C++将字符串传递给 C 库以进行内存管理
- 从函数返回时C++内存管理
- 函数指针和 lambda 的内存管理
- 自定义内存管理器在发布模式下工作正常,但在调试模式下则不然
- C++中的内存管理
- C和C++中的内存管理有什么区别
- 字符 * 未从重载运算符或内存管理问题正确返回
- 如何在源代码中使用执行策略检测 C++17 的扩展内存管理算法的可用性?
- 底层指针和内存管理
- 智能指针,避免使用QNetworkAccessManager时进行手动内存管理
- c++中的内存管理问题
- 使用矢量时的内存管理
- 循环和内存管理中的指针算术C++?
- C++堆栈内存管理问题
- C 内存管理中的课程如何管理 - 研究
- 不可变数据模型的内存管理
- C++ 使用数组初始化时的 STL 向量内存管理
- SFML 纹理内存管理