-6

I was working with an example regarding seg fault:

char m[10]="dog";
strcpy(m+1,m);

In my centOs machine the result was as expected: segmentation fault. but on Ubuntu nothing happen. then I add a printf("%s",m); to the code on ubuntu and surprisingly I got the "ddog" as result. I am using GCC and the ubuntu version was the latest. can anyone tell me why the results are different. I also check it on raspbian and I also received segmentation fault.

Thanks,

P0W
  • 46,614
  • 9
  • 72
  • 119
Mahdi
  • 377
  • 1
  • 4
  • 8

2 Answers2

3

This causes undefined behaviour. strcpy may only be used between areas that do not overlap.

To fix this code you could write:

memmove(m+1, m, strlen(m) + 1);
Community
  • 1
  • 1
M.M
  • 138,810
  • 21
  • 208
  • 365
1

The memory for m is:

+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+

Whe you initialize it with:

char m[10] = "dog";

the first four elements m are initialized. The rest are initialized.

+---+---+---+----+---+---+---+---+---+---+
| d | o | g | \0 | ? | ? | ? | ? | ? | ? |
+---+---+---+----+---+---+---+---+---+---+

I am using ? to indicate uninitialized memory locations. They could contain anything.

Let's walk through the execution of

strcpy(m+1, m);

step by step.

Step 1: m[0] is copied to m[1]. So you have:

+---+---+---+----+---+---+---+---+---+---+
| d | d | g | \0 | ? | ? | ? | ? | ? | ? |
+---+---+---+----+---+---+---+---+---+---+

Step 2: m[1] is copied to m[2]. So you have:

+---+---+---+----+---+---+---+---+---+---+
| d | d | d | \0 | ? | ? | ? | ? | ? | ? |
+---+---+---+----+---+---+---+---+---+---+

Step 3: m[2] is copied to m[3]. So you have:

+---+---+---+---+---+---+---+---+---+---+
| d | d | d | d | ? | ? | ? | ? | ? | ? |
+---+---+---+---+---+---+---+---+---+---+

strcpy terminates when it encounters the null character in the source argument. As you can see, the terminating criteria for strcpy will never be met. Hence, the program keeps on reading data from memory beyond the valid limits and writing data to memory beyond valid limits.

That is cause for undefined behavior.

To get the desired result, "ddog", you can to use:

size_t len = strlen(m);
for ( int i = len; i >= 0; --i )
{
   m[i+i] = m[i];
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270