Deutsch English Français Italiano |
<87jzh0gdru.fsf@nosuchdomain.example.com> View for Bookmarking (what is this?) Look up another Usenet article |
Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson <Keith.S.Thompson+u@gmail.com> Newsgroups: comp.lang.c Subject: Re: relearning C: why does an in-place change to a char* segfault? Date: Thu, 01 Aug 2024 13:59:49 -0700 Organization: None to speak of Lines: 53 Message-ID: <87jzh0gdru.fsf@nosuchdomain.example.com> References: <IoGcndcJ1Zm83zb7nZ2dnZfqnPWdnZ2d@brightview.co.uk> <v8fhhl$232oi$1@dont-email.me> <v8fn2u$243nb$1@dont-email.me> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Injection-Date: Thu, 01 Aug 2024 22:59:52 +0200 (CEST) Injection-Info: dont-email.me; posting-host="933b865835dd2da7485caeddca825875"; logging-data="2515784"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19AiqHY3tXvZ1sRJHXi2CQi" User-Agent: Gnus/5.13 (Gnus v5.13) Cancel-Lock: sha1:VBlJVkWdLeoQRIvGpkuFNxPAWrY= sha1:OxiXBE1BZ2OjiwE12P2f6fH90o0= Bytes: 3005 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.com void Void(void) { Void(); } /* The recursive call of the void */