2010-10-06 18 views
7

devo occuparmi dell'allocazione della memoria, dell'ambito e dell'eliminazione dell'oggetto "stringa" C++?allocazione stringa C++

ad esempio:

#include <string> 

const char* func1() { 
    const char* s = "this is a literal string"; 
    return s; 
} 

string func2() { 
    std::string s = "this is a literal string"; 
    return s; 
} 

const char* func3() { 
    std::string s = "this is a literal string"; 
    return s.c_str(); 
} 

void func() { 
    const char* s1 = func1(); 
    std::string s2 = func2(); 
    const char* s3 = func3(); 

    delete s1; //? 
    delete s3; //? 
} 

func2: Non ho bisogno di 'eliminare' s2. func3: devo cancellare 's3'?

btw, is func1 è corretto? Il contenuto della memoria dei caratteri è ancora disponibile dopo aver abbandonato l'ambito func1? Se sì, dovrei eliminarlo quando non ne ho più bisogno?

+0

http://stackoverflow.com/questions/2579874/lifetime-of-a-const-string-literal-returned-by-a-function – elgcom

+0

http://stackoverflow.com/questions/267114/scope-of -string-letterals – elgcom

risposta

16
  • func1() restituisce un puntatore a una stringa letterale. Non è necessario eliminare i valori letterali stringa.
  • func2() (presumibilmente, si omette il prefisso std::) restituisce un std::string. Si prende cura di se stesso.
  • func3() restituisce un puntatore a una stringa gestita da un oggetto std::string che viene distrutto quando la funzione viene chiusa. Non devi toccare quel puntatore dopo che la funzione è tornata.
  • Lei avrebbe dovuto prendersi cura della memoria restituita da questa funzione:

    const char* func4() { 
        char* s = new char[100]; 
        // fill char array with a string 
        return s; 
    } 
    

Tuttavia, la gestione delle risorse manuale è difficile. Per i principianti, se una funzione restituisce un puntatore nudo, non si sa se punta a un oggetto (char) oa un array e se è necessario eliminarlo. Dovresti evitare tutto questo e limitarti a std::string.

+0

ora è OK, non lo era prima :) –

+0

Nulla che io possa vedere. –

3

Si ha un diverso problema con s3, vale a dire che la funzione func3() restituisce un puntatore in un oggetto che esce dall'ambito quando la funzione ritorna. Non farlo.

Per chiarire: l'oggetto stringa locale all'interno di func3() cesserà di esistere al momento del ritorno della funzione, quindi non è necessario eliminare. Tuttavia, hai ancora un puntatore al suo buffer interno, che tu restituisci. Non puoi usarlo.

molto buona e dettagliata risposta passato qui, per non più confusione deriva: Is it more efficient to return a const reference

+0

@Alexander Rautenberg - Meglio sarebbe chiedergli di usare un riferimento per s3, piuttosto che un puntatore. Ed è corretto comunque. – DumbCoder

+0

Il problema rimane lo stesso per func3() o s3, se si utilizza un puntatore o un riferimento. Non c'è nulla di corretto nel modo in cui func3() è codificato. –

+0

@Alexander Rautenberg - Non in un riferimento, per archi, se si controlla correttamente. Restituire un oggetto ma legarlo a un oggetto const ne aumenta la durata fino a quando il programma non si chiude. Se restituisce una stringa invece di un puntatore char, sta bene. – DumbCoder

1

ho snip il codice relativo a ciascuna funzione e il trattamento del suo valore di ritorno, e commentare qui sotto:

const char* func1() { 
    const char* s = "this is a literal string"; 
    return s; 
} 
const char* s1 = func1(); 
delete s1; //? 

Non puoi cancellare s1, come la stringa a cui punta non vive sul mucchio.

string func2() { 
    string s = "this is a literal string"; 
    return s; 
} 
string s2 = func2(); 

Questo va bene. func2 's s esce dal campo di applicazione e pulisce. s2 duplicherà la stringa da s e si pulirà automaticamente alla fine di func.

const char* func3() { 
    string s = "this is a literal string"; 
    return s.c_str(); 
} 
const char* s3 = func3(); 
delete s3; //? 

func3 restituisce un puntatore a una stringa che è stato liberato. Otterrai una doppia eccezione gratuita dopo l'esecuzione di delete s3.

1

In func3 la stringa locale viene creata dal compilatore chiamando il costruttore implicito string(const char*) inizializzando il proprio buffer interno con una copia della stringa letterale. Quindi si restituisce un puntatore al buffer interno della stringa che esce immediatamente dall'ambito e viene liberato non appena la funzione ritorna.

Problemi correlati