2013-06-27 5 views
1
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 - избежать утечек памяти

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

расПредеЛения памяти indivisual элемента T_testStepDetails: ----

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

Append к списку: ---

testCaseStepslist->append(*testStepMessageBuffer); 

свободная память: ----

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

Так, чтобы освободить память выше шаги достаточно, чтобы предотвратить утечку памяти ?

Или для каждой структуры типа T_testStepDetails в списке я должен освободить память для внутреннего char* члены для whome я динамически распределяемой памяти ?

ответ

1

вы должны вызвать delete[] на каждом char* вы создали с new[].

Рассмотрите возможность использования QByteArray или QString вместо или char*.

3

Обратите внимание, что вам не нужно динамически создавать список, контейнеры Qt явно используются для чтения и могут быть даже переданы как значение без глубокой копии. Созданный в стеке QList может быть даже немного быстрее из-за меньшей степени.

Я также замечаю, что вы используете комбинацию простого динамического распределения, динамического распределения простого массива, а также счетного подсчитанного контейнера. Хотя в этом нет ничего особенного, но лучше решить, будете ли вы использовать конструкции низкого уровня или высокого уровня ради равномерности, как упоминал Риттехо, вы можете избежать использования конструкций высокого уровня на всем пути и полностью избегайте ручного управления памятью, учитывая, что у вас нет ограничений, чтобы не использовать их ... То, что у вас сейчас, просто беспорядочно, даже если это не обязательно неправильно.

Поскольку объект, который вы храните в списке, не является QObject, вы можете даже уйти с сохранением фактических элементов вместо указателя на них (QObject s не могут быть скопированы, чтобы вы могли хранить только указатели для них в контейнерах), потенциально в последовательном контейнере, чтобы свести к минимуму потраченное впустую пространство памяти и получить еще лучшую производительность. QList будет даже де-распределять и уничтожать (если есть что-либо) все экземпляры, когда они попадают «из области видимости». В вашем текущем сценарии вы используете обычные указатели, которые не имеют деструктора и, естественно, не выделяют свою память.

Итак, мои предложения:

  • использование QString вместо char *
  • использование QScopedPointer<T> вместо T * или просто хранить фактические экземпляры (например, значение)
  • распределение использование стека везде, где это возможно

Это уменьшает вероятность утечки памяти до минимума.Плюс я думаю, что хорошо избегать сценариев «указатель на список указателей на сценарии указателей на символы» - вы делаете его излишне сложным на поверхности, а с более высокими конструкциями вся эта сложность будет скрыта от вас, а управление памятью будет автоматический.

2

Прежде всего, поскольку вы используете Qt, представляется целесообразным заменить char * на QString. Это позволяет избавиться от транзакций памяти массивов char *. Затем рассмотрите каждый случай, когда вы распределяете память динамически: возможно, вы можете использовать только объекты, связанные с стеком. Например,

QList<T_testStepDetails>* testCaseStepslist = new QList<T_testStepDetails>(); 

на первый взгляд кажется излишним. Вы всегда можете передать список по ссылке. Также вы можете выделить append стек выделенных объектов в свой список, не нужно создавать его динамически, а затем копировать.

Смежные вопросы