2

I am getting Segmentation fault after return executes. Why is it coming after return and not in strcpy?

int main()
{

     char a[2];

     strcpy(a,"0123456789101112131415161718192021222324252627282930");
     printf("%s\n",a);

     return 0;

}
Daksh Shah
  • 2,997
  • 6
  • 37
  • 71
deeps
  • 65
  • 3
  • 1
    It's undefined behaviour. Segmentation fault is a reasonable outcome :) – P.P May 02 '14 at 16:36
  • 1
    you are trying to copy a long string into a 2 characters array... – giorashc May 02 '14 at 16:37
  • 3
    The strcpy writes the data to the stack, which can certainly succeed. But it is quite possibly destroying the return address stored on the stack, so the return jumps to an invalid location. – Mark Wilkins May 02 '14 at 16:38
  • Segmentation Fault is a (lucky) manifestation of Undefined Behavior – Arun May 02 '14 at 16:39

4 Answers4

4

I am getting Segmentation fault after return executes. Why is it coming after return and not in strcpy?

You have made a common mistake called a buffer overflow. This results in undefined behavior, which is a standards answer. However, if you understand how a typical machine uses a stack, you can understand why it crashes when you return. Most CPUs use a down ward growing stack. So before you call strcpy, the stack is something like,

sp + 0 : a[0]
sp + 1 : a[1]
sp + 2 : padding
sp + 3 : padding
sp + 4: return address (four bytes)

The compiler machinery creates a call frame each time you use a function in 'C'. The return address exists as part of stack where the compiler allocates space for your a[] array. As it is under-sized for the string copy, you over-write the return address. This value isn't used until you return. The return address will be overwritten with something like the value 0x34353637 which is the binary pointer for the ASCII text '4567'.

It is advisable to use something like strncpy or an alternative. For example,

strncpy(a,"012345678...", sizeof(a));
a[sizeof(a)-1] = 0;   /* ensure the string is terminated. */

Obviously you need to increase the size of your 'a' array if you want the full string to be printed.

Community
  • 1
  • 1
artless noise
  • 21,212
  • 6
  • 68
  • 105
3

Why is it coming after return and not in strcpy?

You get the segmentation fault when main returns because you overwrite critical data (saved frame pointer and return address) in the stack frame of main function and not in the stack frame of strcpy function.

As others already said, you invoke undefined behavior and anything can happen: from nothing to a nuclear war.

ouah
  • 142,963
  • 15
  • 272
  • 331
  • 1
    I am fairly certain that nothing in my toolchain can possibly cause nuclear war upon encountering undefined behavior in my code. (If I were working at NORAD, I might be less certain.) – AShelly May 02 '14 at 17:24
1

You're trying to load a string with a lot more than 2 characters into a char array that only holds 2 characters. This will cause a segmentation fault, since you are overwriting the memory allocated for the char array, which can also cause undefined behavior.

ElGavilan
  • 6,610
  • 16
  • 27
  • 36
  • The OP's question isn't why it causes a segfault, but why it happens at return, not at `strcpy`. – kviiri May 02 '14 at 16:39
  • As I stated in my answer, it happens because you are overwriting past the memory location allocated for that char array. Undefined behavior means literally anything can happen; it is possible to overwrite the instruction code of the program, you could overwrite another variable in memory elsewhere, etc. There's really no easy way to tell exactly what happens. It could be that the instruction code is overwritten, causing execution to jump elsewhere in memory, causing the segfault... – ElGavilan May 02 '14 at 16:41
0

Your program overwrote the buffer, that would cause undefined behavior, which means literally anything could happen.

Lee Duhem
  • 14,695
  • 3
  • 29
  • 47