C ++ вектор в куче вместо стека - PullRequest
6 голосов
/ 13 февраля 2011

Я столкнулся с интересной проблемой. У меня есть функция в C ++, которая возвращает вектор, полный классов. Как только вектор возвращается, он вызывает деконструкции для каждого класса, который является элементом в векторе. Проблема очевидна: данные уничтожаются там, где класс указывает на указатели, которые освобождаются при уничтожении объекта. Я могу только предположить, что деконструкторы вызываются, потому что вектор находится в стеке, а не в куче.

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

Alex

Ответы [ 3 ]

4 голосов
/ 13 февраля 2011

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

Если вы предпочитаете, чтобы ваша функция возвращала вектор по значению , убедитесь, что объекты внутри вектора реализуют конструктор копирования (и, возможно, оператор присваивания тоже не уверен в этом).Имея это, пожалуйста, не забывайте о Правиле Трех .

1 голос
/ 01 июня 2012

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

0 голосов
/ 24 октября 2016

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

Похоже, вы не определили свои конструкторы копирования должным образом.Например:

class ThisIsWrong
{
public:
    ThisIsWrong()
    {
        i = new int;
        *i = rand();
    }
    ~ThisIsWrong()
    {
        delete i;
        i = nullptr;
    }

    int value() const
    {
        return *i;
    }

private:
    int* i;
};

void foo()
{
    vector<ThisIsWrong> wronglets;
    wronglets.push_back(ThisIsWrong());
    return wronglets;
}

void main()
{
    vector<ThisIsWrong> w = foo();
    w[0].value(); // SEGFAULT!!
}

Вам необходимо либо удалить конструкторы копирования и присваивания (которые затем превратят это в ошибку компиляции вместо времени выполнения), либо реализовать их должным образом.

...