Memory allocation for string and char array

I cannot understand how memory is allocated in the following code:

#include<stdio.h>
#include<string.h>

int main()
{
    char a[]={"text"};
    char b[]={'t','e','x','t'};
    printf(":%s: sizeof(a)=%d, strlen(a)=%d\n",a, sizeof(a), strlen(a));
    printf(":%s: sizeof(b)=%d, strlen(b)=%d\n",b, sizeof(b), strlen(b));
    return 0;
}

Output signal

:text: sizeof(a)=5, strlen(a)=4
:texttext: sizeof(b)=4, strlen(b)=8

Studying the memory addresses and the output code, it seems that the variable b is placed before the variable a, and therefore strlen (b), looking for \ 0, returns 8. Why is this happening? I expected the variable a to be declared first.

+5
source share
4 answers

The language does not give any guarantees as to what is placed there. So, your experiment makes little sense. It might work, maybe not. The behavior is undefined. Yours is bnot a string, and UB uses strlensomething that is not a string.

, , , (, x86), .. . , , , (a first b second), b , a. b a .

, , . ( ) , , , , . , , "" , , , , " " .

+7

"b" . , char a [] :

char a[] = { 't', 'e', 'x', 't', '\0' };

strlen (b) undefined, NULL (0 ).

+2

, , : http://ideone.com/zHhHc

:text: sizeof(a)=5, strlen(a)=4
:text

, , : http://codepad.org/MXJWY136

:text: sizeof(a)=5, strlen(a)=4
:text: sizeof(b)=4, strlen(b)=4

, ++, : http://ideone.com/aLNjv

:text: sizeof(a)=5, strlen(a)=4
:text: sizeof(b)=4, strlen(b)=4

, - / . undefined (UB) - , char (\ 0). ...

a, b , , .

char a[] = "text";

:

----------------------
| t | e | x | t | \0 |
----------------------

" " \0 ( 5). b , 4. b b strlen() , . char, .

+1

Linux/x86 GCC -S, . , b [] , [], strlen (b) = 4.

    .file   "str.c"
    .section    .rodata
    .align 4
.LC0:
    .string ":%s: sizeof(a)=%d, strlen(a)=%d\n"
    .align 4
.LC1:
    .string ":%s: sizeof(b)=%d, strlen(b)=%d\n"
    .text
.globl main
    .type   main, @function
main:
    pushl   %ebp
    movl    %esp, %ebp
    andl    $-16, %esp
    subl    $32, %esp
    movl    %gs:20, %eax
    movl    %eax, 28(%esp)
    xorl    %eax, %eax
    movl    $1954047348, 19(%esp)
    movb    $0, 23(%esp)
    movb    $116, 24(%esp)
    movb    $101, 25(%esp)
    movb    $120, 26(%esp)
    movb    $116, 27(%esp)
    leal    19(%esp), %eax
    movl    %eax, (%esp)
    call    strlen
    movl    %eax, %edx
    movl    $.LC0, %eax
    movl    %edx, 12(%esp)
    movl    $5, 8(%esp)
    leal    19(%esp), %edx
    movl    %edx, 4(%esp)
    movl    %eax, (%esp)
    call    printf
    leal    24(%esp), %eax
    movl    %eax, (%esp)
    call    strlen
    movl    $.LC1, %edx
    movl    %eax, 12(%esp)
    movl    $4, 8(%esp)
    leal    24(%esp), %eax
    movl    %eax, 4(%esp)
    movl    %edx, (%esp)
    call    printf
    movl    $0, %eax
    movl    28(%esp), %edx
    xorl    %gs:20, %edx
    je  .L2
    call    __stack_chk_fail
.L2:
    leave
    ret
    .size   main, .-main
    .ident  "GCC: (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2"
    .section    .note.GNU-stack,"",@progbits

In the code above $ 1954047348, followed by $ 0, there is [] with zero completion. After that, four bytes b []. This means that b [] was pushed onto the stack before [], as the stack grows on this compiler.

If you compile with -S (or equivalent), you should see b [] at a lower address than [], so you get strlen (b) = 8.

+1
source

All Articles