2012-12-03 11 views
18

Ciągle pojawia się błąd "Konwersja z literału napisanego w łańcuchu znaków na znak * jest nieaktualna" w moim kodzie. Celem kodu jest użycie wskaźnika do wskaźnika, aby przypisać ciąg1 i łańcuch2 słowo, a następnie wydrukować. Jak mogę to naprawić?Konwersja z literału łańcuchowego na char * jest przestarzała.

Oto mój kod:

#include <iostream> 
using namespace std; 

struct WORDBLOCK 
{ 
    char* string1; 
    char* string2; 
}; 

void f3() 
{ 
    WORDBLOCK word; 

    word.string1 = "Test1"; 
    word.string2 = "Test2"; 


    char *test1 = word.string1; 
    char *test2 = word.string2; 

    char** teststrings; 

    teststrings = &test1; 
    *teststrings = test2; 

    cout << "The first string is: " 
     << teststrings 
     << " and your second string is: " 
     << *teststrings 
     << endl; 
} 
+1

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. –

+0

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) –

Odpowiedz

39

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.)

+0

To był niewiarygodne jasne, pomysłowe i pouczające. Dziękuję za pomoc, teraz rozumiem o wiele lepiej! –

+0

Wyjaśnienie jest wspaniałe, ale kod jest niejasny i mylący - wygląda na to, że spodziewasz się wydrukować "Test1" i "Test2", podczas gdy faktycznie drukujesz wartość łańcuchów testowych (przesunięcie wskazujące na "test1") i ciąg znaków do 'test1' (który jest" Test2 ", ponieważ zmodyfikowałeś' test1' przez teststrings) – neuviemeporte

+0

@neuviemeporte: (Wiem, że jestem trochę spóźniony.) Wszystko, co zrobiłem, to dodać potrzebne słowa kluczowe 'const' do kodu OP . Nie próbowałem wprowadzać żadnych innych poprawek ani ulepszeń. –

Powiązane problemy