Вектор указателей: требуется некоторое пояснение

Я много читал о векторе указателей на этом форуме, но мне трудно понять идею удаления указателей, хранящихся в векторе. Ниже приведен мой запрос:

Предположим, я динамически создаю массив объектов

CPoint* dynamic_array;
dynamic_array = new CPoint[30714];

Теперь мне нужно использовать эти значения в объекте другого класса через вектор указателей

vector<CPoint*> vector_of_pointers;

Затем я разделю элементы dynamic_array на объекты другого класса, используя следующие

Class B{
    vector<CPoint*> vector_of_pointers;
public:
    void function(CPoint* a){
        if (some condition){
            vector_of_pointers.push_back(a);
        }
};

Где a всегда будет указателем на объект из dynamic_array

Затем я планирую удалить первоначально созданный dynamic_array после того, как потребность в его объектах отпадет.

delete[] dynamic_array;

Нужно ли удалять каждый указатель в векторе даже после этого? И если надо, то можно ли это сделать в деструкторе для Class B?

Извините, если это простой или глупый вопрос, но я новичок в С++, и для моего приложения необходимо использовать контейнер.


person akash_c    schedule 14.08.2013    source источник
comment
Скорее всего, вы просто хотите std::vector<CPoint>. Если вам нужен указатель, используйте интеллектуальный указатель.   -  person chris    schedule 14.08.2013
comment
Элементы вектора удалять не нужно. На самом деле это будет ошибкой. После вызова delete[]` вы не можете разыменовывать элементы.   -  person juanchopanza    schedule 14.08.2013
comment
Я считаю, что проблема здесь связана с владением памятью. Как только вы удалите dynamic_array, указатели в вашем векторе будут указывать на недопустимые места в памяти. Последовательное использование векторов может помочь. Возможно, вы захотите взглянуть на boost::ptr_vector или boost::shared_ptr   -  person Kilian Brendel    schedule 14.08.2013


Ответы (4)


Чтобы ответить на ваш первоначальный вопрос: нет, вам не нужно удалять отдельные объекты CPoint (на самом деле вы не можете).

Но я считаю, что вам лучше использовать vector<CPoint> для хранения фактической точки, а не указателя на нее.

person Mats Petersson    schedule 14.08.2013

Указатели, которые вы храните в своем vector<CPoint*>, указывают на объекты, которые вы уже deleted с помощью своей инструкции delete[] dynamic_array, поэтому вам не нужно, а также не следует добавлять инструкции delete к отдельным указателям, хранящимся в вашем векторе.

person Thomas Kühn    schedule 14.08.2013

Нужно ли удалять каждый указатель в векторе даже после этого? А если нужно, то можно ли это сделать в деструкторе для класса B?

Ответ - нет, и на самом деле вы не можете.

Будет ли лучше просто использовать std::vector, я думаю, это зависит от ваших потребностей, но я могу подтвердить, что использование new[] намного быстрее, чем создание каждого объекта по отдельности. Иногда:

class CPoint {
public:
    float x; float y;
}

const int N = 1e6;
for(int i = 0; i < N; ++i)
{
    new CPoint();
}
// 122 ms

CPoint* points = new CPoint[N];
// 0.00793176 ms

std::vector<CPoint*> vectorPoints(N); // same as above
// 4.48263 ms

Использование std::vector<CPoint*>(N) также быстро, но не быстрее, чем new[]

person McLeary    schedule 14.08.2013

удаление объектов CPoint, на которые указывают указатели в векторе, не требуется и невозможно, но указатели в векторе должны быть удалены из вектора.

вы должны очистить вектор, поскольку он содержит не менее 4*number_of_elements (8*number_of_elements в системах x64) бесполезных указателей.

person Zaki    schedule 14.08.2013