Path: csiph.com!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: relearning C: why does an in-place change to a char* segfault? Date: Thu, 01 Aug 2024 14:28:37 -0700 Organization: None to speak of Lines: 61 Message-ID: <874j84gcfu.fsf@nosuchdomain.example.com> References: <87jzh0gdru.fsf@nosuchdomain.example.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Injection-Date: Thu, 01 Aug 2024 23:28:38 +0200 (CEST) Injection-Info: dont-email.me; posting-host="933b865835dd2da7485caeddca825875"; logging-data="2515784"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+lNwPR+W5788m1cX1VIjDT" User-Agent: Gnus/5.13 (Gnus v5.13) Cancel-Lock: sha1:5tGkezqxPkMmmDfKlMtm7gnxNik= sha1:3gd4zGUG3kloCWSZCMZvpYx0dH4= Xref: csiph.com comp.lang.c:387246 Bart writes: > On 01/08/2024 21:59, Keith Thompson wrote: >> Bart 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 >>>>> #include >>>>> >>>>> 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. > > What's the difference between such an object, and an array like one of > these: > > static char A[100]; > static char B[100]={1}; > > Do these not also have static storage duration? Yet presumably these > can be legally modified. Perhaps you thought I meant to imply that objects with static storage duration are read-only. I didn't. I wrote "A string literal creates an array object with static storage duration. Any attempt to modify that array object has undefined behavior." Both statements are true, and neither follows from the other. An array object associated with a string literal has static storage duration because the standard says so. Attempting to modify such an object has undefined behavior because the standard says so. -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com void Void(void) { Void(); } /* The recursive call of the void */