C++ literały ciągów znaków są tablice constchar
, co oznacza, że nie może legalnie je zmodyfikować.
Jeśli chcesz bezpiecznie przypisać ciąg dosłownego do wskaźnika (co wiąże się z niejawnego array-to-wskaźnik konwersji), trzeba zadeklarować wskaźnik docelowy jako const char*
, nie tylko jako char*
.
Oto wersja kodu, który kompiluje bez ostrzeżenia:
#include <iostream>
using namespace std;
struct WORDBLOCK
{
const char* string1;
const char* string2;
};
void f3()
{
WORDBLOCK word;
word.string1 = "Test1";
word.string2 = "Test2";
const char *test1 = word.string1;
const char *test2 = word.string2;
const char** teststrings;
teststrings = &test1;
*teststrings = test2;
cout << "The first string is: "
<< teststrings
<< " and your second string is: "
<< *teststrings
<< endl;
}
zastanowić się, co może się zdarzyć, jeśli język nie nakłada to ograniczenie:
#include <iostream>
int main() {
char *ptr = "some literal"; // This is invalid
*ptr = 'S';
std::cout << ptr << "\n";
}
A (nie const
) char*
pozwala modyfikować dane wskazywane przez wskaźnik. Jeśli mógłbyś przypisać literał łańcuchowy (niejawnie przekonwertowany na wskaźnik do pierwszego znaku ciągu) na zwykły char*
, mógłbyś użyć tego wskaźnika do modyfikacji literału ciągu bez ostrzeżeń z kompilatora. Nieważne kod powyżej, czy to zadziałało, by wydrukować
Some literal
- a to może faktycznie zrobić na niektórych systemach. Jednak w moim systemie umiera z powodu błędu segmentacji, ponieważ próbuje zapisywać w pamięci tylko do odczytu (nie fizycznej pamięci ROM, ale pamięci, która została oznaczona jako tylko do odczytu przez system operacyjny).
(Na marginesie: Zasady c za rok napisowych różnią się od zasad C++ 's W C, ciąg dosłowny jest tablicą char
, nie tablicą const char
- ale próbuje zmodyfikować to zachowanie niezdefiniowane To.. oznacza, że w C możesz legalnie napisać char *s = "hello"; s[0] = 'H';
, a kompilator niekoniecznie narzeka - ale program prawdopodobnie umrze z błędem segmentacji po uruchomieniu go, co ma na celu zachowanie wstecznej kompatybilności z kodem C napisanym przed const
Hasło zostało wprowadzone. C++ miał const
od samego początku, więc ten konkretny kompromis nie było konieczne.)
mam edytowany kod nieco, reforma Instrukcja wyjściowa tak, aby można ją było odczytać bez przewijania i dodając kilka niezbędnych wierszy u góry. –
Znakowanie jako duplikat dla przyszłych wyszukiwań [przestarzałe konwersji z ciągiem do dosłownego „char \ *”] (http://stackoverflow.com/questions/9650058/deprecated-conversion-from-string-literal-to-char) –