| Deutsch English Français Italiano |
|
<877ccxdu44.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: Sat, 03 Aug 2024 17:11:55 -0700
Organization: None to speak of
Lines: 85
Message-ID: <877ccxdu44.fsf@nosuchdomain.example.com>
References: <IoGcndcJ1Zm83zb7nZ2dnZfqnPWdnZ2d@brightview.co.uk>
<20240801114615.906@kylheku.com> <v8gs06$2ceis$1@dont-email.me>
<v8jlnk$31hqf$1@dont-email.me> <PttrO.6301$UJj9.4591@fx33.iad>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Injection-Date: Sun, 04 Aug 2024 02:11:56 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="d07bdb3c66a7f25ead61bbbbc164c6d5";
logging-data="3865857"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+Hcd/CBbuMMOoZEDR2SHYl"
User-Agent: Gnus/5.13 (Gnus v5.13)
Cancel-Lock: sha1:TcLfZJR8p3vVCKET7Vl1IE4rS74=
sha1:VnTdc3FQbUC0Vn8sADG8VIwZPxI=
Bytes: 4602
scott@slp53.sl.home (Scott Lurndal) writes:
> David Brown <david.brown@hesbynett.no> writes:
>>On 01/08/2024 22:42, Bart wrote:
>>> char text[]="this is a test";
>>>
>>> But this can be changed without making the program self-modifying.
>>
>>"this is a test" is a string literal, and is typically part of the
>>program's image. (There are some C implementations that do things
>>differently, like storing such initialisation data in a compressed format.)
>>
>>The array "char text[]", however, is a normal variable of type array of
>>char. It is most definitely not part of the program image - it is in
>>ram (statically allocated or on the stack, depending on the context) and
>>is initialised by copying the characters from the string literal (prior
>>to main(), or at each entry to its scope if it is a local variable).
>
> Linux (ELF):
>
> A file-scope static declaration of char text[] will emit the string
> literal into the .data section and that data section will be loaded
> into memory by the ELF loader. There is no copy made at runtime
> before main().
>
> #include <stdint.h>
> #include <stdlib.h>
> #include <stdio.h>
>
> char text1[] = "This is a test of a static-scope string";
In the abstract machine, there's an anonymous array object corresponding
to the string literal, and `text` is a distinct object, also with static
storage duration. The compiler optimizes it away and only stores the
data in `text`.
> int
> main(int argc, const char **argv)
> {
> char text2[] = "This is a test of a function-scope string";
Since the second string literal is identical, the compiler is permitted
to store them in the same place (it's unspecified, so the implementation
doesn't have to document this). Presumably there's code to copy from
the static array into `text2`, executed within `main`.
>
> fprintf(stdout, "%p %s\n", &text1, text1);
> fprintf(stdout, "%s\n", text2);
>
> return 0;
> }
>
> $ /tmp/a
> 0x601060 This is a test of a static-scope string
> This is a test of a function-scope string
>
> $ objdump -p /tmp/a
>
> /tmp/a: file format elf64-x86-64
>
> Program Header:
> PHDR off 0x0000000000000040 vaddr 0x0000000000400040 paddr 0x0000000000400040 align 2**3
> filesz 0x00000000000001f8 memsz 0x00000000000001f8 flags r-x
> INTERP off 0x0000000000000238 vaddr 0x0000000000400238 paddr 0x0000000000400238 align 2**0
> filesz 0x000000000000001c memsz 0x000000000000001c flags r--
> LOAD off 0x0000000000000000 vaddr 0x0000000000400000 paddr 0x0000000000400000 align 2**21
> filesz 0x00000000000007dc memsz 0x00000000000007dc flags r-x
> LOAD off 0x0000000000000e10 vaddr 0x0000000000600e10 paddr 0x0000000000600e10 align 2**21
> filesz 0x0000000000000278 memsz 0x0000000000000290 flags rw-
>
> .data section:
>
> 0000e00: 0000 0000 0000 0000 0000 0000 0000 0000 ................
[36 lines deleted]
> 0001050: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> 0001060: 5468 6973 2069 7320 6120 7465 7374 206f This is a test o
> 0001070: 6620 6120 7374 6174 6963 2d73 636f 7065 f a static-scope
> 0001080: 2073 7472 696e 6700 4743 433a 2028 474e string.GCC: (GN
>
> $ printf "0x%x\n" $(( 0x601060 - 0x0000000000600e10 ))
> 0x250
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */