Question

I have a program like this(x86_64 GNU/Linux)

int main()
{
    char s[] = "123456789";
    char d[] = "123";
    strcpy(d, s);

    printf("%p, %0p\n", s, d);
    printf("%s, %s", s, d);

    return 0;
}

and the output is : 0xeb6d2930 0xeb6d2910 123456789 123456789 I am little confused with the result I think the program in the memory is like this:

  • '9','\0' . .
  • '5','6','7','8'
  • 0x7fff813af310: '1','2','3','4'
  • 0x7fff813af300: '1','2','3','\0'

so the result should be *s = "789", *d = "123456789"

could you guys explain why the result isn't as I thought? I changed the format specifier to %p to print the address of d and s I know that s and d are overlapped so there is not enough space for d to hold s which may lead to undefined behaviour,but anyway I was wondering why the result is *s = "123456789" *d = "123456789"

Was it helpful?

Solution

From the output you show the address layout and it's initial content seem to be:

       offset 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f  
d: 0xeb6d2910 30 31 32 00 xx xx xx xx xx xx xx xx xx xx xx xx | 1 2 3 . . . . . . . . . . . . .
   0xeb6d2920 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx | . . . . . . . . . . . . . . . .
s: 0xeb6d2930 30 31 32 33 34 35 36 37 38 39 00 xx xx xx xx xx | 1 2 3 4 5 6 7 8 9 . . . . . . . 

After the strcpy(d, s):

       offset 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f  
d: 0xeb6d2910 30 31 32 33 34 35 36 37 38 39 00 xx xx xx xx xx | 1 2 3 4 5 6 7 8 9 . . . . . . . 
   0xeb6d2920 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx | . . . . . . . . . . . . . . . .
s: 0xeb6d2930 30 31 32 33 34 35 36 37 38 39 00 xx xx xx xx xx | 1 2 3 4 5 6 7 8 9 . . . . . . . 

However, as for d fewer memory had been allocated as used during strcpy() the code invokes undefeind behaviour.

OTHER TIPS

Your program has undefined behavior on these two counts:

  • Buffer overflow with strcpy(): Do not write to memory you do not own.
  • Wrong format specifier for printf(): Use %p to print pointer addresses. Only works for data-pointers though.

Please use the proper prototype for main, you nearly have it (this might be UB, though I did not follow all the argument):

int main(void)
int main(int argc, char* argv[])

or compatible or implementation defined extensions are valid.

Undefined Behavior means everything goes, even nasal demons.

Your program invokes undefined behavior because:
1. d doesn't have enough space to hold the string larger than 4 bytes (including \0).
2. You are using wrong format specifier to print the address.

Result is either expected or unexpected.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top