2014-01-23 8 views
0

Я пытаюсь разобраться в некоторых проблемах с памятью на C++, в первую очередь с контейнерами, содержащими указатели. Скажем, у меня есть что-то вроде этого:Освобождение памяти от элементов контейнера

header.h

#ifndef test_Header_h 
#define test_Header_h 

#include <vector> 

using std::vector; 

class ClassA { 
    int* intPtr; 

public: 
    ClassA(int n); 
    ~ClassA(); 
}; 

class ClassB { 
    vector<ClassA*> vecPtr; 

public: 
    ClassB(); 
    ~ClassB(); 

    void someFunc(); 
}; 

#endif 

main.cpp

#include <iostream> 
#include "Header.h" 

int main(int argc, const char * argv[]) 
{ 
    ClassA objA(5); 
    ClassB objB; 

    return 0; 
} 

ClassA::ClassA(int n) { 
    intPtr = new int[n]; 
} 
ClassA::~ClassA() { 
    delete intPtr; 
} 

ClassB::ClassB() { 
    vecPtr = vector<ClassA*>(0); 
} 

ClassB::~ClassB() { 
    //no destructor needed 
} 

void ClassB::someFunc() { 
    //vecPtr = something using new; 
    int* testPtr = new int[vecPtr.size()]; 
    //do stuff 
    delete testPtr; 
} 

ли vecPtr когда-либо должны быть удалены? Или деструктор ClassA выполнит это для меня? Кроме того, если вместо vector, будет ли такая же ситуация, если бы я использовал list указателей или pair? Наконец, для разъяснения testPtr необходимо удалить в someFunc, потому что это область, в которой она была объявлена, поэтому положить ее в деструктор будет бессмысленно. Если testPtr поделился адресом адрес важного участника, удалив его также важным членом? Я знаю, что есть довольно много вопросов, но я думаю, что я просто кругом спорю в голове, все больше и больше запутываю себя.

+0

Вы назначили intPtr с 'new int [n];', поэтому вы должны освободить его с помощью delete []. См. [Документация] (http://www.cplusplus.com/reference/new/operator%20delete [] /). – user2079303

+0

Угадайте, пожалуйста, о usecase: вам, скорее всего, нужно явно «удалить» каждый элемент 'vecPtr' и предоставить конструктор/назначение копии, который скопирует содержимое указателей для использования в целевом векторе. – qwm

+0

Вы должны «удалить» все, что вы создали, с помощью 'new'. –

ответ

2

vecPtr не нужно удалять, потому что это не указатель. Это может отличаться для указателей в vecPtr и зависит от того, кто имеет право владения этими указателями.

Да, testPtr необходимо удалить, где он доступен. Ничего другого даже не будет компилировать. Если вы укажете testPtr члену и удалите его, вы, вероятно, увидите двойную свободную ошибку или ошибку коррупции, когда элемент будет удален на деструкторе.

В общем, если что-то должно быть удалено до реализации. Единственное, что вам нужно обратить внимание, это то, что каждый новый получает ровно одно удаление из любого места в любом коде. Обычно конструкторы/деструктор - это хорошее место.

0

У вас здесь большие проблемы. Помните об этом:

1) любой new должен быть сбалансирован с помощью delete.

2) любой new[] должен быть сбалансирован с помощью delete[].

Фактически, если вы их смешиваете (как вы это сделали), у вас есть undefined поведение. Бум! Вам нужно написать delete[] intPtr; и delete[] testPtr;

Также и попросту говоря, вы не пишете delete vecPtr, так как вы не писали new vecPtr.

Внутренне среда выполнения C++ запоминает количество элементов, выделенных с помощью new[]. Вы должны использовать delete[], чтобы эта среда выполнения могла получить доступ к этой информации.

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