2012-02-16 3 views
7

Можно ли вернуть вектор, заполненный локальными переменными?Безопасно вернуть вектор, заполненный локальными переменными?

Например, если у меня есть ...

#include <vector> 

struct Target 
{ 
public: 
    int Var1; 
    // ... snip ... 
    int Var20; 
}; 


class Test 
{ 
public: 
    std::vector<Target> *Run(void) 
    { 
     std::vector<Target> *targets = new std::vector<Target>; 
     for(int i=0; i<5; i++) { 
      Target t = Target(); 
      t.Var1 = i; 
      // ... snip ... 
      t.Var20 = i*2; // Or some other number. 
      targets->push_back(t); 
     } 
     return targets; 
    } 


}; 

int main() 
{ 
    Test t = Test(); 
    std::vector<Target> *container = t.Run(); 

    // Do stuff with `container` 
} 

В этом примере я создаю множественным Target экземпляров в цикле, толкая их к вектору, и возвращает указатель на него. Поскольку экземпляры Target были выделены локально, в стек, означает ли это, что возвращаемый вектор является небезопасным, потому что он ссылается на объекты в стеке (которые вскоре могут быть перезаписаны и т. Д.)? Если да, то какой рекомендуемый способ вернуть вектор?

Я пишу это на C++, кстати.

+0

Возможный дубликат [Динамическое распределение памяти векторов в C++] (http://stackoverflow.com/questions/9252523/dynamic-memory-allocation-of-vectors-in-c) –

ответ

14

Элементы копируются, когда вы push_back их в вектор (или присваиваете элементам). Поэтому ваш код безопасен - элементы в векторе не являются ссылками на локальные переменные, они принадлежат вектору.

Кроме того, вам даже не нужно возвращать указатель (и never обрабатывать необработанные указатели, вместо этого использовать интеллектуальные указатели). Просто верните копию; компилятор достаточно умен, чтобы оптимизировать это, чтобы не было сделано реальной избыточной копии.

+2

Я бы не сказал, что никогда не обрабатывал сырые указатели - все имеет свое место. Однако возврат по значению, не вызывающий копию, теперь является официальным благодаря новому стандарту C++ 11 и перемещению конструкторов. – Carl

+2

@ carleeto: Это было официально в течение многих лет с (N) RVO. – ildjarn

+0

Я переставал беспокоиться о возвращающихся указателях с RVO в GCC 3.1 :) Однако, «никогда не обрабатывать сырые указатели» *? Я пошел бы с carleeto на этом и не соглашался с вами, у них есть их использование. Но все равно, +1. – netcoder