Can't dereference pointer to stack?

T

TuAmigoFiel

Why does the following give a segmentation fault?

void breakme(char* st) {
char* cp = st;
*cp = 'x' // This is the problem line.
}

int main() {
char* mine = "teststringfortestingpurposes";
breakme(mine);
}
 
A

Alf P. Steinbach

* (e-mail address removed):
Why does the following give a segmentation fault?

void breakme(char* st) {
char* cp = st;
*cp = 'x' // This is the problem line.
}

int main() {
char* mine = "teststringfortestingpurposes";
breakme(mine);
}

Why not?

The program has undefined behavior.

Therefore, anything can happen, including a SIGSEGV.

If instead you ask, why does C++ allow that particular nastie?

That's to maintain backwards compatibility with C.
 
R

roberts.noah

Why does the following give a segmentation fault?

void breakme(char* st) {
char* cp = st;
*cp = 'x' // This is the problem line.
}

int main() {
char* mine = "teststringfortestingpurposes";

This string is constant and cannot be changed. Change to "char mine[]
= " and it will work. This is because you will be declairing an array
of char instead of a pointer to an unmutable string.
 
D

dakka

Why does the following give a segmentation fault?

void breakme(char* st) {
char* cp = st;
*cp = 'x' // This is the problem line.
}

int main() {
char* mine = "teststringfortestingpurposes";
breakme(mine);
}
Modifying a static string literal is - whilst legal - undefined. The
statement
char* mine = "teststringfortestingpurposes";
is actually converting a const char * to char * (again which is legal
but deprecated). Result - undefined. In your case (probably most
compilers will do the same) - dummy spit.

--dakka
 
T

TuAmigoFiel

Thanks everyone.

This was from a string manipulation function I wrote that was seemingly
not working. The worst part is that it would have worked if I hadn't
used a string literal to test it.
 
J

jesper

hmm..
now I'm getting worried. Has something happened with c++, that
I am not aware of?
you can even do:(if you like to i dont see why though)
void breakme(char* st) {
char* cp = st;
*cp = 'x'; }


int main() {
breakme("teststringfortestingpurposes");
}
This is a basic pointer..
I am a bit confused now.
And just so you know, I tested this (borland compiler set to ansi
complience and force c++ compile).
Please help me understand.
/Jesper
 
D

Default User

hmm..
now I'm getting worried. Has something happened with c++, that
I am not aware of?
you can even do:(if you like to i dont see why though)
void breakme(char* st) {
char* cp = st;
*cp = 'x'; }


int main() {
breakme("teststringfortestingpurposes");
}
This is a basic pointer..
I am a bit confused now.
And just so you know, I tested this (borland compiler set to ansi
complience and force c++ compile).
Please help me understand.

Understand what? You don't mention what it is that confuses you.

The code fragments shown exhibit undefined behavior. It may seem like a
tautology, but there is no defined behavior for undefined behavior. The
code is broken and should not be used, but you can't expect anything in
particular from it.



Brian
 
K

Kaz Kylheku

Alf said:
* (e-mail address removed):

Why not?

The program has undefined behavior.

Therefore, anything can happen, including a SIGSEGV.

If instead you ask, why does C++ allow that particular nastie?

That's to maintain backwards compatibility with C.

The idea that modification of literals is undefined in C++ for the sake
of compatibility with C is quite ridiculous.

Other languages have similar restrictions against what is essentially
self-modifying code.

Modification of literals is also undefined in Lisp for instance. Is
that for compatibility with C also?

(setf (car '(a b c)) 42) ;; Nasal demons!
(setf (char "abc" 1) #\z) ;; ditto

This type of liberty with respect to literals allows for ROM-able code:
both the program code and its literal data can be compiled into a
single program image, which can then be put into write-protected
memory. The program can reference that data using a direct pointer into
that memory.

A literal should be thought of as a component of the program itself,
and not some external data. Through a literal quoting mechanism, a
program gains access to a piece of itself which it can use as data in a
computation.

If such objects had to be modifiable, then only their initial values
could be stored in that read-only memory. Modifiable storage would have
to be allocated for them at program startup, and the initial values
copied there. This is a waste of time and storage for objects which are
treated as immutable.

And let's not forget that immutable objects can also be compressed
together to save space through substructure sharing. If one string
literal matches a suffix of another, or possible the entire string,
then it can be represented as a pointer to that suffix. If those
objects could be modified, there would be surprising behaviors.
Changing one literal would change some unrelated string that shares
storage with it.

Many C and C++ implementations for virtual memory systems provide a
nice, accurate diagnostic for this error. The compiler places string
literals into the same object file sections as code, so literals are
co-allocated with code. The dynamic loader maps the program's
executable image file into the process address space as read only, so
any self modification (code or literal data) results in an instant
violation. It's a nice setup.
 
B

Bo Persson

hmm..
now I'm getting worried. Has something happened with c++, that
I am not aware of?
you can even do:(if you like to i dont see why though)
void breakme(char* st) {
char* cp = st;
*cp = 'x'; }


int main() {
breakme("teststringfortestingpurposes");
}
This is a basic pointer..

Yes, but the type of the string literal is 'const char*'. It is
convertible to non-const char*, just to be compatible with old C code.

Actually modifying (*cp = 'x';) the const data is what is the
undefined behaviour.

On some other compilers, this would cause a segfault, as the string
literal could be stored in a read-only segment. As usual though, one
possible outcome of the undefined behaviour is the nasty 'seems to
work'.
I am a bit confused now.

We all are. .-)


Bo Persson
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,679
Members
48,796
Latest member
Greg L.

Latest Threads

Top