2012-02-16 11 views
7

È sicuro restituire un vettore che è stato riempito con variabili locali?Sicuro per restituire un vettore popolato con variabili locali?

Per esempio, se ho ...

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

In questo esempio, sto creando molteplici Target casi in un ciclo for, spingendoli al vettore, e restituendo un puntatore ad esso. Poiché le istanze Target sono state allocate localmente, nello stack, significa che il vettore restituito non è sicuro perché fa riferimento a oggetti nello stack (che potrebbero presto essere sovrascritti, ecc.)? In tal caso, qual è il modo consigliato per restituire un vettore?

Sto scrivendo questo in C++, a proposito.

+0

possibile duplicato di [Allocazione dinamica della memoria di vettori in C++] (http://stackoverflow.com/questions/9252523/dynamic-memory-allocation-of-vectors-in-c) –

risposta

14

Gli elementi vengono copiati quando si push_back in un vettore (o si assegnano agli elementi). Il tuo codice è quindi sicuro: gli elementi nel vettore non fanno riferimento a variabili locali, sono di proprietà del vettore.

Inoltre, non è nemmeno necessario restituire un puntatore (e mai gestire i puntatori non elaborati, utilizzare invece i puntatori intelligenti). Basta invece restituire una copia; il compilatore è abbastanza intelligente da ottimizzarlo in modo tale che non venga effettuata alcuna copia ridondante.

+2

Non direi mai gestire puntatori grezzi - tutto ha il suo posto. Tuttavia, il ritorno di valore che non causa una copia è ora ufficiale grazie al nuovo standard C++ 11 e ai costruttori di movimento. – Carl

+2

@carleeto: è stato ufficiale per anni con (N) RVO. – ildjarn

+0

Ho smesso di preoccuparmi di restituire i puntatori da RVO in GCC 3.1 :) Tuttavia, * "non gestisco mai i puntatori grezzi" *? Andrei con Carleeto su questo e non sono d'accordo con te, loro hanno i loro usi. Ma hey, +1 comunque. – netcoder

Problemi correlati