Распределение всей памяти, связанной со структурой в C ++ - PullRequest
0 голосов
/ 23 апреля 2019

У меня есть структура, которая содержит несколько векторов, определенных следующим образом:

#include <vector>
using namespace std;

struct data{
    vector<float> x;
    vector<float> y;
    vector<float> z;
}

, которые я позже использую как таковые:

data d;
for(int i; i<3; i++){
    d.x.push_back(i)
    d.y.push_back(i*2)
    d.z.push_back(i*3)
}

И теперь я хочу безопасно удалитьdata таким образом, полностью освобождает всю память, связанную с ним.Я думаю, что способ сделать это - написать простой деструктор, который очищает и освобождает каждое поле data, а затем delete объект:

struct data{
    vector<float> x;
    vector<float> y;
    vector<float> z;

    ~data(){
        vector<tempObject>().swap(x);
        vector<tempObject>().swap(y);
        vector<tempObject>().swap(z);
    }
}

, и тогда это должно работать:

data d;
    for(int i; i<3; i++){
        d.x.push_back(i)
        d.y.push_back(i*2)
        d.z.push_back(i*3)
    }
delete data;

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

Будет ли это работать?Если нет, можете ли вы описать, почему и / или предложить альтернативу?Я понимаю, что память будет освобождена, как только d выйдет из области видимости, но мне нужно освободить память до того, как это произойдет.

Ответы [ 3 ]

1 голос
/ 23 апреля 2019

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

В C ++ есть переменные с автоматической, статической и динамической длительностью хранения. Время жизни автоматического хранения, которое у вас есть в вашем примере и статическом, контролируется компилятором, поэтому вы не можете изменить их время жизни (маленькое исключение - продление значения rvalue по ссылке, но это не связано здесь). Если вам нужно вручную управлять временем жизни, вам нужно создать переменную с динамическим сроком хранения:

auto d = std::make_unique<data>();
d->x.push_back(1.0);
...
d.reset(); // terminate of lifetime of variable pointed by d manually
1 голос
/ 23 апреля 2019

Когда struct уничтожено, его члены будут уничтожены (в обратном порядке объявления). Уничтоженные таким образом vector очистят их собственную память.

Нет необходимости в собственном деструкторе.

0 голосов
/ 23 апреля 2019

удаление не требуется, так как в качестве стекового объекта у вас есть "данные d".

vector (как и большинство других контейнеров stl позаботятся о вашей очистке).

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

если вы используете современный c ++ и управляете своими объектами кучи с помощью shared_ptr или unique_ptr, вам (почти) никогда не нужно использовать ключевые слова new и delete.

пример:

#include <vector>
#include <memory>

struct MyData
{
    std::vector<float> x;
    std::vector<float> y;
    std::vector<float> z;
};

int main()
{
    //example 1: stack object
    {
        MyData d;
        for(int i = 0; i<3; i++)
        {
            d.x.push_back(i);
            d.y.push_back(i*2);
            d.z.push_back(i*3);
        }
    } // scope of d ends, everything including the vectors are cleaned up


    //example 2: heap object  
    {
        std::unique_ptr<MyData> dataPtr = std::make_unique<MyData>();
        for(int i = 0; i<3; i++)
        {
            dataPtr->x.push_back(i);
            dataPtr->y.push_back(i*2);
            dataPtr->z.push_back(i*3);
        }
    } // scope of dataPtr ends, everything will be cleaned up

    //example 3: heap object, clean up within scope
    {
        std::unique_ptr<MyData> dataPtr = std::make_unique<MyData>();
        for(int i = 0; i<3; i++)
        {
            dataPtr->x.push_back(i);
            dataPtr->y.push_back(i*2);
            dataPtr->z.push_back(i*3);
        }

        dataPtr.reset(); // this will clean-up whatever the pointer points to

    } // scope of dataPtr ends, ptr itself is destoryed

}
...