Удалить массив объектов очереди - PullRequest
2 голосов
/ 22 марта 2011

Я работаю над объектом, который содержит массив queues с длиной массива, которая не определена до вызова конструктора. В основном это выглядит примерно так:

#include <queue>

class myClass{
public:
  //public functions
private:
  //private functions and variables

  queue<int>* myQueue;
};

инициализируется так:

myClass::myClass(int numOfQueues){
  myQueue = new queue<int>[numOfQueues];
}

Кажется, все это прекрасно работает. он работает точно так, как я надеялся, но теперь каждый раз, когда я выхожу из программы, я получаю ошибку сегментации. В классе есть несколько других массивов, которые инициализируются таким же образом, но они имеют типы bool и int вместо очереди. Мой деструктор выглядит так:

myClass::~myClass(){
  delete boolArray;
  delete intArray;
  delete myQueue;
}

Теперь я предполагаю, что этот деструктор работает для указателей boolArray и intArray, потому что я не начинал получать ошибку, пока не добавил myQueue. Кто-нибудь знает, как правильно написать деструктор? Возможно ли, что это все, что я должен сделать, и деструктор просто не вызывается в нужное время?

Ответы [ 4 ]

7 голосов
/ 22 марта 2011

Поскольку вы выделили, используя new[], вы должны сделать delete[] myQueue; в деструкторе. В противном случае это вызовет неопределенное поведение. Кстати, вы можете использовать std::vector<std::queue<int> >, если не хотите получать проблемы с управлением памятью такого типа.

3 голосов
/ 22 марта 2011

Почему вы не используете std::vector вместо массивов?

Вам нужно delete[] массивы, а не delete - вы наделены new[]

1 голос
/ 22 марта 2011

Использование delete с new[] не только вызовет утечку памяти, но и вызовет неопределенное поведение.

Правильная форма delete для использования с new[]: delete[].

Однако в идиоматическом C ++ всегда рекомендуется использовать std::vector вместо массивов в стиле C. Вам не нужно явно управлять памятью самостоятельно, когда вы используете контейнеры STL.

0 голосов
/ 22 марта 2011

Навин уже решил проблему. Я хотел бы добавить хорошую практику программирования.

Следующий пример использования также создаст проблемы удаления.

void foo()
{
    myClass a;
    myClass b(a);
}

когда мы объявляем a , будет создан новый экземпляр myQueue. Однако при объявлении b будет вызван конструктор копирования вместо myClass :: myClass (int numQueues) конструктор. Таким образом a .myQueue == b .myQueue .

При выходе из функции foo , деструктор a удалит myQueue , затем деструктор b попытается удалить указатель без ссылки , который может привести к фатальной ошибке.

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

private:
    myClass(const myClass&);
    const myClass& operator=(const myClass&);

См. Также boost :: NonCopyable

...