2009-03-16 23 views
11

Mam prosty program i dostaję naruszenie dostępu pod adresem *(str + start). Czemu? Powinienem móc to zmienić. Dobrze?Jak rozwiązać problem z błędem lokalizacji zapisu?

void fn() 
{ 
    char *str = "Hello wordl!"; 
    int end = strlen(str); 
    int start = 0; 
    end--; 
    while(start < end) 
    { 
     *(str + start) = *(str + end); <--- Access violation writing location *(str + Start). 
     end--; 
     start++; 
    } 
} 

Odpowiedz

4

Nie, nie powinieneś. "Witaj świecie" jest stałym ciągiem literowym, musisz przydzielić pamięć używając malloc() w C lub new w C++, jeśli chcesz mieć pamięć, którą możesz dowolnie modyfikować.

2

To dlatego, że piszesz do magazynu literału ciągów, który może znajdować się w chronionym obszarze pamięci.

25

char *str = "Hello World"; jest ciągiem stałym i nie może być modyfikowany. Kompilator może umieścić go w niezapisywalnej lokalizacji, co spowoduje awarię.

Zastąpienie deklaracji przez char str[] = "Hello World"; powinno zrobić, co chcesz, umieszczając napis w tablicy, która można modyfikować na stosie.

+0

Twoja sugestia byłaby identyczna z aktualnym kodem. –

+0

char str [] versus char * str powoduje, że łańcuch jest modyfikowalny. – Michael

+0

Oto kilka odnośników do tego: http://www.iso-9899.info/wiki/StringsByEypropiele https://www.securecoding.cert.org/confluence/display/cplusplus/STR30-CPP.+Do + nie + próba + modyfikacja + ciąg + literały – Michael

3

Jak zauważyli inni, ciągi literałów mogą być przechowywane w obszarze pamięci przeznaczonym tylko do odczytu. Czy kompilujesz z włączonymi ostrzeżeniami? Powinieneś otrzymać ostrzeżenie o odrzuceniu stałej literału.

Co można zrobić zamiast tego jest:

char *str = strdup("Hello, world!"); 
// Modify the string however you want 
free(str); 
Powiązane problemy