2013-05-17 13 views
13

Mi chiedo se ho frainteso qualcosa: un costruttore di copia da std::stringnon copia il suo contenuto?std :: costruttore di stringhe di stringhe NON in profondità in GCC 4.1.2?

string str1 = "Hello World"; 
string str2(str1); 

if(str1.c_str() == str2.c_str()) // Same pointers! 
    printf ("You will get into the IPC hell very soon!!"); 

Questo stamperà "Otterrete nell'inferno IPC molto presto !!" e mi infastidisce

Si tratta del normale comportamento di std::string? Ho letto da qualche parte che di solito fa una copia profonda.

Tuttavia, questo funziona come previsto:

string str3(str1.c_str()); 

if(str1.c_str() == str3.c_str()) // Different pointers! 
    printf ("You will get into the IPC hell very soon!!"); 
else 
    printf ("You are safe! This time!"); 

Si copia il contenuto nella nuova stringa.

+0

Provate a modificare 'str2' nel primo esempio (ad esempio' str2 [0] = 'B'; ') e * poi * confrontando il' c_str () valori. – Angew

+0

Per quello che vale, GCC 4.7 ha lo stesso comportamento sia in modalità C++ 03 e C++ 11 (e il suggerimento di @ Angew produce infatti valori 'c_str()' diversi). – syam

+0

Appare in modo allettante un nuovo buffer dopo la modifica u sugestato @Angew. Quindi sembra essere una sorta di "ottimizzazione" ... ci è costato diverse ore di lavoro per trovare quel problema. * Sigh * –

risposta

14

È del tutto possibile che l'implementazione string utilizzi la funzione copy-on-write che spiegherebbe il comportamento. Anche se questo è meno probabile con le più recenti implementazioni (e non conformi su implementazioni C++ 11).

Lo standard non pone alcuna restrizione sul valore del puntatore restituito da c_str (oltre a ciò punta a una c-string con terminazione null), quindi il codice è intrinsecamente non portatile.

+0

Perché la COW è meno probabile con le implementazioni più recenti. – user93353

+2

@ user93353 COW non è possibile implementare se si desidera essere conformi a C++ 11: http://stackoverflow.com/questions/12199710/legality-of-cow-stdstring-implementation-in-c11 – pmr

+0

@ user93353: COW può ridurre drasticamente le prestazioni in ambienti con multithreading. Per questo motivo ha perso molta popolarità (ed è stato vietato in C++ 11). – Grizzly

5

std::string l'implementazione nel proprio compilatore deve essere conteggiata. Cambia una delle stringhe e poi controlla di nuovo i puntatori: sarebbero diversi.

string str1 = "Hello World"; 
string str2(str1); 

if(str1.c_str() == str2.c_str()) // Same pointers! 
    printf ("You will get into the IPC hell very soon!!"); 

str2.replace(' ',','); 

// Check again here. 

Questi sono 3 articoli eccellenti su stringhe conteggio di riferimento.

http://www.gotw.ca/gotw/043.htm

http://www.gotw.ca/gotw/044.htm

http://www.gotw.ca/gotw/045.htm

+0

L'ho fatto, come ho sottolineato nel mio commento sulla domanda stessa e come detto sopra: ne fa una copia su scrittura! –