[C++] Zmienianie elementu tablicy przechowującej C-string


(Lol600000065) #1

Czesc,

Mam takie pytanko odnosnie tablic przechowujących stałe dosłowne typu C-string. Adres takiej tablicy można przypisać do wskaźnika na const char*. Ale dlaczego nie można zmieniać jakiegoś elementu tej tablicy nawet za pomocą rzutowania const_cast ? O np. tak:

const char* ptr = "Jakis sobie C-string";const_castchar*(ptr+1)) = '#'; [/code]

bo nastąpi segfault (Access violation - czyli naruszenie segmentacji pamięci). A przecież takie obiekty statyczne jak np. te tablice (bo C-stringi mają automatycznie przydomek 'static') przechowuje się w obszarze zwanym Data area (jest on w Data segmencie):

[quote="Wikipedia"]

The Data area contains global and static variables used by the program that are not initialized to zero. This segment can be further classified into initialized read-only area and initialized read-write area. For instance the string defined by char s[] = "hello world"; in C and a C statement like int debug=1; outside the main would be stored in initialized read-write area. And a C statement like char *string = "hello world"; makes the string literal "hello world" to be stored in initialized read-only area and the character pointer variable string in initialized read-write area.
[/quote]


 :arrow: http://en.wikipedia.org/wiki/Data_segment

I dlaczego następuje segfault ? Program niby narusza pamięć, ale ten obszar pamięci [u]należy do niego samego[/u], a nie do innego programu :!: ...

([alex]) #2

To zależy od kompilatora. mingw oraz gcc umieszcza takie stałe w segmencie READONLY. Każde sięgnięcie do tego segmentu z próbą zapisu daje "segment fault".


(Lol600000065) #3

Hmm, a na przykład taki program nie spowoduje nic w Visualu - zadnego segfaulta:

#include using namespace std;

([alex]) #4

const int& ref = 56; // powinno zostać umieszczone na stosie :smiley:


(Lol600000065) #5

Tzn. ? Chodzi Ci o stałą dosłowną '56' (bo ref jest na stosie) :?:

Bo jeśli tak to dalej nie wiadomo czemu nie można uzyskać jej adresu (dokładniej adresu obiektu, do którego została przypisana wartość 56), przecież obiekty na stosie adres mają...


([alex]) #6

ref też, ale chodziło mi o samą stałą.

Można uzyskać jej adres: adr=&ref;


(Lol600000065) #7

No można uzyskać, ale nie bezpośrednio tylko przez ref ^.^