Nawet wiedząc, że widzieliście, że robią to samo lub że .data () wywołuje .c_str (), nie jest poprawne zakładanie, że tak będzie w przypadku innych kompilatorów. Możliwe jest również, że Twój kompilator zmieni się w przyszłej wersji.
2 powody, dla których warto używać std :: string:
std :: string może być używany zarówno dla tekstu, jak i dowolnych danych binarnych.
//Example 1
//Plain text:
std::string s1;
s1 = "abc";
//Example 2
//Arbitrary binary data:
std::string s2;
s2.append("a\0b\0b\0", 6);
Powinieneś użyć metody .c_str (), gdy używasz swojego ciągu jako przykładu 1.
Powinieneś użyć metody .data (), gdy używasz swojego ciągu jako przykładu 2. Nie dlatego, że użycie .c_str () jest niebezpieczne w takich przypadkach, ale ponieważ jest bardziej wyraźne, że pracujesz z danymi binarnymi dla innych przeglądających Twój kod.
Możliwa pułapka z użyciem .data ()
Poniższy kod jest nieprawidłowy i może spowodować awarię w programie:
std::string s;
s = "abc";
char sz[512];
strcpy(sz, s.data());//This could crash depending on the implementation of .data()
Dlaczego często implementujące programy powodują, że .data () i .c_str () robią to samo?
Ponieważ jest to bardziej wydajne. Jedynym sposobem, aby .data () zwróciło coś, co nie jest zakończone wartością zerową, byłoby skopiowanie ich wewnętrznego bufora .c_str () lub .data () lub po prostu użycie 2 buforów. Posiadanie pojedynczego bufora zakończonego wartością null zawsze oznacza, że podczas implementacji std :: string można zawsze użyć tylko jednego buforu wewnętrznego.
.data()
inne niż stałe dla , więc nie są one już równoważne dla niestałych ciągów.