qlist - 避免内存泄漏

时间:2013-06-27 11:42:23

标签: qt qlist

typedef struct {
    char *u8_testStep;
    char *u8_functionTested;
    char *u8_testDescription;
    char *u8_expectedResponse;
    char *u8_packetTx;
    char *u8_packetRx;
    char *u8_passFail;
    char *u8_comment;
}T_testStepDetails;
为类型T_testStepDetails创建的

列表: -

QList<T_testStepDetails>* testCaseStepslist = new QList<T_testStepDetails>();
QString strTemp;
T_testStepDetails *testStepMessageBuffer = new T_testStepDetails;

将记忆分配给T_testStepDetails的个人元素:----

testStepMessageBuffer->u8_testStep = new char[strTemp.length()];
// copy value to the pointer
qstrcpy(testStepMessageBuffer->u8_testStep, strTemp.toStdString().c_str());

附加到列表:---

testCaseStepslist->append(*testStepMessageBuffer);

免费记忆:----

if(!list.isEmpty())
{
    qDeleteAll(list);
    list.clear();
}

所以释放上面的内存步骤足以防止内存泄漏?

或者对于列表中T_testStepDetails类型的每个结构,我必须释放内部char*成员的内存,以便我动态分配内存?

3 个答案:

答案 0 :(得分:3)

请注意,您不需要动态实例化列表,显式共享Qt容器以进行读取,甚至可以作为值传递而不会发生深层复制。由于间接性较低,在堆栈上创建的QList甚至可能会更快一些。

我还注意到你正在使用普通动态分配,普通数组动态分配以及引用计数容器的组合。虽然没有什么特别的错误,但最好是为了统一而决定你是使用低级别还是高级别的结构,正如Riateche所提到的,你可以一直使用高级结构和完全避免手动内存管理,考虑到你没有限制不使用那些...你现在拥有的只是凌乱,即使不一定是错误的。

由于您在列表中存储的对象不是QObject派生的,您甚至可以通过存储实际元素而不是指向它们的指针(QObject s无法复制,因此您只能存储在容器中指向它们的指针),可能在顺序容器中,以最大限度地减少浪费的内存空间并获得更好的性能。 QList甚至会在所有实例“超出范围”时解除分配并销毁(如果有任何内容)。在您当前的场景中,您使用常规指针,它们没有析构函数,并且自然不会取消分配它们的内存。

所以,我的建议:

  • 使用QString代替char *
  • 使用QScopedPointer<T>代替T *或仅存储实际实例(例如价值)
  • 尽可能使用堆栈分配

这可以将内存泄漏的可能性降至最低。另外我认为避免“指向指向字符指针结构的指针列表的指针”是好的 - 你在表面上使它变得不必要地复杂,更高的结构所有这些复杂性将对你隐藏并且内存管理将是自动的。

答案 1 :(得分:2)

首先,由于您使用的是Qt,因此将char *替换为QString似乎是合理的。这可以让你摆脱char *数组内存交易。然后考虑你动态分配内存的每种情况:可能你只能使用堆栈分配的对象。例如,

QList<T_testStepDetails>* testCaseStepslist = new QList<T_testStepDetails>();
乍一看似乎是多余的。您始终可以通过引用传递列表。您也可以append将已分配的对象堆叠到列表中,动态创建它然后复制是不必要的。

答案 2 :(得分:1)

您必须使用delete[]为您创建的每个char*拨打new[]

请考虑使用QByteArrayQString代替char*