2010-04-29 14 views
7

Quindi, sto cercando di capire meglio come funzionano i letterali di stringa in C++. Sono principalmente interessato alle situazioni in cui si assegna l'indirizzo di una stringa letterale a un puntatore e lo si passa in giro. Ad esempio:Quanto sono sicuri e affidabili i letterali di stringa C++?

char* advice = "Don't stick your hands in the toaster."; 

Ora diciamo che passo semplicemente questa stringa copiando i puntatori per la durata del programma. Certo, probabilmente non è una buona idea, ma sono curioso di sapere cosa succederebbe dietro le quinte.

Per un altro esempio, diciamo che facciamo una funzione che restituisce una stringa letterale:

char* foo() 
{ 
    // function does does stuff 
    return "Yikes!"; // somebody's feeble attempt at an error message 
} 

Ora lascia dire questa funzione viene chiamata molto spesso, e la stringa letterale viene utilizzato solo circa la metà del tempo si chiama :

// situation #1: it's just randomly called without heed to the return value 
foo(); 

// situation #2: the returned string is kept and used for who knows how long 
char* retVal = foo(); 

Nella prima situazione, cosa sta effettivamente accadendo? La stringa è appena stata creata ma non è stata utilizzata e non è mai stata rilasciata?

Nella seconda situazione, la stringa verrà mantenuta finché l'utente ne avrà bisogno? Cosa succede quando non è più necessario ... verrà liberato quel ricordo (supponendo che nulla punti più a quello spazio)?

Non fraintendetemi, non ho intenzione di utilizzare stringhe letterali come questa. Sto pensando di usare un container per tenere sotto controllo le mie stringhe (probabilmente std :: string). In genere voglio solo sapere se queste situazioni potrebbero causare problemi di gestione della memoria o di dati danneggiati.

+8

I letterali di stringa C++ sono perfettamente sicuri e affidabili. Sono i programmatori che usano le stringhe letterali che non sono sicure e affidabili. –

+0

Questo è quello che stavo pensando; Ho solo bisogno di rassicurazione, credo. Grazie. :) –

risposta

22

Stringhe letterali hanno il tipo const char[N] (dove N è la lunghezza + 1) e sono allocate in modo statico. Non devi preoccuparti dei problemi di memoria; se una stringa viene utilizzata nel programma, viene gestita interamente per te e risiede in qualche parte nella memoria del programma (di solito in sola lettura).

Cioè, questi sono "lo stesso":

static const char str[] = "a string"; 
"a string" 

Quando si punta ad una stringa letterale, si punta al primo carattere a matrice. Infatti, poiché il tipo è const char[], è sicuro indicarlo tramite lo const char*. La conversione da stringa letterale a char* è deprecata e non sicura.

// the "same" 
static const char str[] = "a string"; 
const char* strPtr = str; // decays 

const char* s1 = "a string"; 
char* s2 = "a string"; // allowed, implicit const_cast 

*s1 = 'A'; // not allowed, it's const 
*s2 = 'B'; // allowed, it's not const (but leads to undefined behavior) 
+5

"La conversione da stringa letterale a char * è deprecata e non sicura." Si. Ha bisogno di stringhe scrivibili se l'hai fatto da qualche parte. Ad ogni modo, NON FARLO. – Joshua

+1

Sì, grazie per aver spiegato l'aspetto const in dettaglio. Ero consapevole che erano costanti, ma ho pensato di lasciare la spiegazione a qualcuno che li capisse meglio di me :) –

+2

Hai detto tutto, per quanto ne so. –

1

primo luogo, dichiarare il valore restituito foo come const, perché stringhe sono costanti che non possono essere modificati senza provocare il temuto "comportamento indefinito". Questo forzerà quindi qualsiasi puntatore che usa il valore di ritorno di foo a essere dichiarato come const, e potenzialmente limitando il danno che può essere (solitamente involontariamente) fatto. I valori letterali delle stringhe sono memorizzati nell'area "testo" di un eseguibile binario - non vengono creati come tali in fase di esecuzione.

Problemi correlati