Getting Segmentation Fault
I saw many questions about getting segmentation fault in C program here in SO, and I thought it would be great to have a reference to those here, a question with some cases that are causing segmentation fault. My answer is posted below.
As written in some answers, the behavior is undefined for all cases, though many people meet them as segmentation fault , so this question is about what causes this "symptom".
In the cases below I get segmentation fault when I run the program, could you determine why?
1)
char *str = "foo";
str[0] = 'b'; // << Segfault hre
2)
char str[] = "foo";
char *newStr = malloc(strlen(str));
strcpy(newStr, str);
free(newStr); // << Segfault here
3)
char *str = malloc(4 * sizeof(char));
str = "foo";
free(str); // << Segfault here
4)
char *str = malloc(4 * sizeof(char));
strcpy(str, "foo");
free(str);
if (str != NULL)
free(str); // << Segfault here
5)
char *str = "something and then foo";
printf("%s", str[19]); // << Segfault here
6)
typedef struct {
char *str;
}st;
...
st *s;
s = malloc(sizeof(st));
s->str = malloc(5);
free(s);
free(s->str); // << Segfault here
All your examples are causing undefined behaviour, which might lead to a crash (or it might not appear to do any harm at all).
You're not allowed to change a string literal. (see eg here)
You forgot to allocate storage for the terminating nul byte, do malloc(strlen(str) + 1);
You're calling free() on a pointer you did not obtain from malloc (or similar functions). As you make the str
pointer point to a string literal, you've lost the pointer to the memory allocated with malloc and leak memory here too.
You're calling free() twice on the same pointer, which is undefined behavior.
%s in the printf format string tells printf that the argument is a string (a char * pointing to a sequence of nul terminated characters) You're passing it a char, not a string. If you want to print the suffix of the string use printf("%s", &str[19]);
You're passing in an invalid pointer to free(), you already free'd s
, you can't dereference it later when you do s->str
. Reverse the order of deallocation: free(s->str); free(s);
free(s->str); free(s);
Case 1:
char *str = "foo";
assign the address of a string in the text segment which is read only, and you can't write to it as done in the second line: str[0] = 'b';
. If you want to modify the text, use char str[] = "foo";
which will create an array of chars on the stack and assign its pointer to str.
case 2:
strlen
returns the length of the string without the '