Reputation: 21
Does the definition:
char arr_of_chars[] = "hello world";
create a constant character array (null terminated) somewhere in memory, and then copy the content of that array to arr_of_chars
, or does it directly assign it to arr_of_chars
?
What exactly is the mechanism that works here?
Upvotes: 0
Views: 150
Reputation: 360
It is subject of storage of the string in c.
Strings can be stored in following ways,
When strings are declared as character arrays, they are stored like other types of arrays in C. For example, if str[] is an auto variable then string is stored in stack segment, if it’s a global or static variable then stored in data segment.
Ex.
char str[] = "Hello_world";
In case of storing the strings using the character pointers, It can be done by two ways,
Read only string in a shared segment.
Ex.
char *str = "Hello_World";
In the above line "Hello_World" is stored in a shared read only location, but pointer str is stored in a read-write memory. You can change str to point something else but cannot change value at present str. So this kind of string should only be used when we don’t want to modify string at a later stage in program.
Dynamically allocated in heap segment.
char *str = NULL;
int size = 6;
str = (char *) malloc(sizeof(char)*size);
*(str+0) = 'H';
*(str+1) = 'E';
*(str+2) = 'L';
*(str+3) = 'L';
*(str+4) = 'O';
*(str+5) = '\0';
Upvotes: 0
Reputation:
What you're asking is not specified by C. In a nutshell, C is specified in terms of an abstract machine and its observable behavior. In this case, this means all you know is there is an array variable arr_of_chars
initialized from a string literal.
When talking about segments, copying, etc, you're already talking about concrete implementations of C and what they're doing. Assuming your arr_of_chars
is at file scope and given a target machine/system that knows binaries with data segments, it would be possible for a C compiler to put the initialized array directly in a data segment -- the observable behavior would be no different from an approach where the runtime first copies the bytes to your array.
Upvotes: 1
Reputation: 309
This will create a null terminated string hello world\0
in the const segment.
In the main function this string will be copied to the character array.
Let me highlight a few lines from the assembly output to clairfy this.
PUBLIC ??_C@_0M@LACCCNMM@hello?5world?$AA@
This creates a public token.
CONST SEGMENT
??_C@_0M@LACCCNMM@hello?5world?$AA@ DB 'hello world', 00H
CONST ENDS
This assigns the constant null terminated string to the token.
lea rax, QWORD PTR arr_of_chars$[rbp]
lea rcx, OFFSET FLAT:??_C@_0M@LACCCNMM@hello?5world?$AA@
mov rdi, rax ; Set destination to stack location
mov rsi, rcx ; Set source to public token
mov ecx, 12 ; Set counter to number of times to repeat
rep movsb ; Copy single byte from source to destination and increment locations
This sets up the source and destination and copies character by character 12 times which is the length of "hello world" and the null terminator. The destination is a location on the stack and the source is the public token.
Upvotes: 0
Reputation: 214475
"...creates a constant character array (null terminated) somewhere in memory, and then copies the content of that array to arr_of_chars"
Indeed. The string literal "hello world"
is stored somewhere in the .rodata
section of the program, unless the compiler managed to optimize it away entirely (depends on your array's scope). From there it is copied into your array.
Upvotes: 0