Удаление разыменованных элементов из вектора - PullRequest
0 голосов
/ 16 февраля 2012

Я создал объекты с помощью new, но затем разыменовал их перед добавлением в вектор. Несмотря на то, что я трахаюсь в интернете, я не могу понять, как я могу вызвать удаление этих объектов. Я хочу сделать это, просто используя стандартные C ++ и STL. Я не хочу (например) использовать библиотеки Boost.

Как видите, a, b и c теряют область видимости, и я остаюсь с тем, что, как я предполагаю, будет копиями в векторе. Как я могу удалить их? Я не хочу хранить указатели в массиве, так как мне нужно будет передать API-функцию массив значений типа double.

Пожалуйста, кто-нибудь - как мне удалить эти объекты?

#include <iostream>
#include <vector>

using namespace std;

vector<double> vectorDouble;
void createObjects();

void createObjects() {
    double* a=new double(13);
    double* b=new double(14);
    double* c=new double(15);
    //a,b and c are not contiguous memory blocks
    cout << "memory location of a: " << a << endl;
    cout << "memory location of b: " << b << endl;
    cout << "memory location of c: " << c << endl;

    vectorDouble.push_back(*a);
    vectorDouble.push_back(*b);
    vectorDouble.push_back(*c);
}

int main() {
    createObjects();
    //the memory addresses are contiguous 8 byte chunks
    cout << "vector memory at 0: " << &(vectorDouble[0]) << endl;
    cout << "vector memory at 1: " << &(vectorDouble[1]) << endl;
    cout << "vector memory at 2: " << &(vectorDouble[2]) << endl;

    //get pointer to the 2nd element
    double *P=&(vectorDouble[1]); 

    //dereference and look inside - two memory locations both contain the value 14
    cout << "vector Pointer P ["<< P <<"] contains " << *P <<endl;

    //Which should I call delete on? I have lost reference to the original pointers.
    //How should I call delete on the vector?

    cout << "deleting pointer that references 2nd vector element" << endl;
    delete P; //********* CRASH **********
    cout << "Done deleting" << endl;
}

Ответы [ 5 ]

2 голосов
/ 16 февраля 2012

Как указывает каждый , нет никаких причин для вызова new в вашей программе:

void createObjects() {
    vectorDouble.push_back(13);
    vectorDouble.push_back(14);
    vectorDouble.push_back(15);
}

Предположим, однако, что у вас есть причина позвонить new. (Я не могу представить, что это может быть, но давайте предположим, что вы гений). Вот как бы вы это сделали:

void createObjects() {
    double* a=new double(13);
    double* b=new double(14);
    double* c=new double(15);
    //a,b and c are not contiguous memory blocks
    cout << "memory location of a: " << a << endl;
    cout << "memory location of b: " << b << endl;
    cout << "memory location of c: " << c << endl;

    vectorDouble.push_back(*a);
    vectorDouble.push_back(*b);
    vectorDouble.push_back(*c);

    delete a;
    delete b;
    delete c;
}

Видите ли, push_back не помещает копию вашего указателя в вектор, он помещает копию вашего объекта в вектор. После того, как вы сделали копию своего объекта, память вашего объекта больше не используется и может быть уничтожена.

2 голосов
/ 16 февраля 2012

Объекты, которые нужно удалить, находятся не в векторе, потому что ваши векторные элементы не создаются с новым. Когда вы используете оператор разыменования в push_back, вы просто передаете копию двойников malloc, а не фактически выделенную двойку для вектора.

Вы на самом деле просто пропускаете их - ваш код будет работать нормально без выделения двойных символов:

void createObjects() {
    vectorDouble.push_back(13);
    vectorDouble.push_back(14);
    vectorDouble.push_back(15);
}
1 голос
/ 16 февраля 2012

Функция createObjects не помещает выделенные значения в вектор; это ввод значений и затем утечка памяти , на которую указывали a, b и c. Звонок:

vectorDouble.push_back(*a);

сохраняет значение, на которое указывает a в векторе (*a разыменовывает указатель, который вы, вероятно, уже знаете). Как только эта функция возвращается, указатели теряются. Вы не можете получить их из вектора. Вам нужно либо сделать вектор указателей на двойники, либо (что более вероятно) даже не распределять значения; просто храните пары.

0 голосов
/ 16 февраля 2012

Ваша утечка в createObjects(), потому что std::vector<>::push_back() делает копию своего аргумента. Вы должны delete указатель до конца области видимости createObjects().

Тем не менее, я не понимаю, почему вы используете динамическое распределение для начала. Если вы можете избежать этого, пожалуйста, сделайте это (и вы можете сделать это с помощью умного указателя типа std::unique_ptr<> или, что еще лучше, с простым старым double с).

0 голосов
/ 16 февраля 2012

Я думаю, у меня проблема, на:

vectorDouble.push_back(*a);
vectorDouble.push_back(*b);
vectorDouble.push_back(*c);

Вы передаете a, b и c в качестве значений, поэтому массив на самом деле не содержит созданных вами переменных (поэтому они теперь имеют другой адрес памяти, они являются копией содержимого ваших переменных!). Затем вы можете удалить переменные внутри метода, не использовать указатели внутри метода или использовать двойной * вектор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...