Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does strcpy trigger a segmentation fault with global variables?

So I've got some C code:

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

/* putting one of the "char*"s here causes a segfault */
void main() {
  char* path = "/temp";
  char* temp;
  strcpy(temp, path);
}

This compiles, runs, and behaves as it looks. However, if one or both of the character pointers is declared as global variable, strcpy results in a segmentation fault. Why does this happen? Evidently there's an error in my understanding of scope.

like image 511
codemonkey Avatar asked Sep 23 '08 18:09

codemonkey


People also ask

Why is strcpy giving segmentation fault?

a segmentation fault occurs when the program tries to write to a part of memory that the kernel does not allow access to. Your 2 char* pointers are not initialized and so could point to anywhere. then when you try to write to these pointer you will get a segmentation fault.

Which is better strcpy or strncpy?

The strncpy function is a safer version of strcpy to copy a string from a source to a destination buffer.

Does strcpy copy null terminator?

The strcpy() function copies string2, including the ending null character, to the location that is specified by string1. The strcpy() function operates on null-ended strings. The string arguments to the function should contain a null character (\0) that marks the end of the string.

Why is strncpy unsafe?

The strncpy() function is insecure because if the NULL character is not available in the first n characters in the source string then the destination string will not be NULL terminated. A program that demonstrates strncpy() in C++ is given as follows.


1 Answers

As other posters mentioned, the root of the problem is that temp is uninitialized. When declared as an automatic variable on the stack it will contain whatever garbage happens to be in that memory location. Apparently for the compiler+CPU+OS you are running, the garbage at that location is a valid pointer. The strcpy "succeeds" in that it does not segfault, but really it copied a string to some arbitrary location elsewhere in memory. This kind of memory corruption problem strikes fear into the hearts of C programmers everywhere as it is extraordinarily difficult to debug.

When you move the temp variable declaration to global scope, it is placed in the BSS section and automatically zeroed. Attempts to dereference *temp then result in a segfault.

When you move *path to global scope, then *temp moves up one location on the stack. The garbage at that location is apparently not a valid pointer, and so dereferencing *temp results in a segfault.

like image 168
DGentry Avatar answered Oct 13 '22 01:10

DGentry