Sujet : Re: relearning C: why does an in-place change to a char* segfault?
De : Keith.S.Thompson+u (at) *nospam* gmail.com (Keith Thompson)
Groupes : comp.lang.cDate : 01. Aug 2024, 21:59:49
Autres entêtes
Organisation : None to speak of
Message-ID : <87jzh0gdru.fsf@nosuchdomain.example.com>
References : 1 2 3
User-Agent : Gnus/5.13 (Gnus v5.13)
Bart <
bc@freeuk.com> writes:
On 01/08/2024 09:38, Richard Harnden wrote:
On 01/08/2024 09:06, Mark Summerfield wrote:
This program segfaults at the commented line:
>
#include <ctype.h>
#include <stdio.h>
>
void uppercase_ascii(char *s) {
while (*s) {
*s = toupper(*s); // SEGFAULT
s++;
}
}
>
int main() {
char* text = "this is a test";
printf("before [%s]\n", text);
uppercase_ascii(text);
printf("after [%s]\n", text);
}
text is pointing to "this is a test" - and that is stored in the
program binary and that's why can't modify it.
>
That's not the reason for the segfault in this case.
I'm fairly sure it is.
With some
compilers, you *can* modify it, but that will permanently modify that
string constant. (If the code is repeated, the text is already in
capitals the second time around.)
>
It segfaults when the string is stored in a read-only part of the binary.
A string literal creates an array object with static storage duration.
Any attempt to modify that array object has undefined behavior. (Which
means there's no guarantee that your program will crash.)
Storing the array in a memory segment that results in a trap on an
attempt to modify it is probably the most common implementation
strategy. Storing the array in writable memory is another, but is rare
these days. (gcc had an option to do this, but it was removed some time
ago).
If you want a pointer to a string literal, it's best to define it as
"const", so attempts to write to it can be caught at compile time:
const char* text = "this is a test";
-- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.comvoid Void(void) { Void(); } /* The recursive call of the void */