2012-02-16 12 views
7

¿Es seguro devolver un vector que se ha llenado con variables locales?¿Es seguro devolver un vector poblado con variables locales?

Por ejemplo, si tengo que ...

#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` 
} 

En este ejemplo, estoy creando múltiples instancias Target en un bucle for, empujándolos al vector, y devolver un puntero a ella. Debido a que las instancias Target se asignaron localmente a la pila, ¿significa eso que el vector devuelto no es seguro porque se refiere a objetos en la pila (que pueden sobrescribirse pronto, etc.)? Si es así, ¿cuál es la forma recomendada de devolver un vector?

estoy escribiendo esto en C++, por cierto.

+0

posible duplicado de [Asignación dinámica de memoria de vectores en C++] (http://stackoverflow.com/questions/9252523/dynamic-memory-allocation-of-vectors-in-c) –

Respuesta

14

elementos se copian cuando se les push_back en un vector (o asignar a los elementos). Por lo tanto, su código es seguro: los elementos en el vector no hacen referencia a las variables locales, son propiedad del vector.

Además, ni siquiera necesita devolver un puntero (y nunca manipular punteros sin procesar, utilice punteros inteligentes en su lugar). Solo devuelve una copia; el compilador es lo suficientemente inteligente como para optimizar esto, de modo que no se realice ninguna copia redundante real.

+2

No diría que nunca maneje punteros crudos: todo tiene su lugar. Sin embargo, volver por valor sin causar una copia ahora es oficial gracias al nuevo estándar C++ 11 y los constructores de movimientos. – Carl

+2

@carleeto: Ha sido oficial durante años con (N) RVO. – ildjarn

+0

Dejé de molestarme con los punteros que regresaban desde RVO en GCC 3.1 :) Sin embargo, * "nunca maneja punteros sin procesar" *? Me gustaría ir con Carleeto en este caso y estar en desacuerdo contigo, tienen sus usos. Pero bueno, +1 de todos modos. – netcoder

Cuestiones relacionadas