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
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 '\0'
chracter at the end, so strlen("foo") = 3
, while strcpy
copies the string including the '\0'
character, so it copies more bytes than you allocated.
case 3:
As in case 1, str = "foo";
assigning the address of "foo" to str
, this means that you lose the address of the allocated memory and str
now contains a pointer to the text segment which you can't free
because it's not on the heap, and its a read-only memory.
case 4:
The free
function doesn't assign NULL
to the pointer received as parameter (since it doesn't have it address, it can't do that). And you are trying to call free
on a buffer that was already free
d.
case 5:
str[19]
is char
, not a char pointer, and "%s"
expects string, meaning char *
. Treated as as an address on many platform, this char is illegal address. printf()
doesn't check the arguments received.
case 6:
The usage of s->str
after s
is free
d is wrong. A correct usage will be to first call free(s->str);
and then call free(s);
. Free the internal allocated memory before free
ing its container.
3: "foo" is a constant string, not allocated dynamically.
Sidenote: That's a memory leak too.
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 e.g. 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()
a pointer not obtained through malloc()
free()
an invalid pointerprintf()
format specifier and actual argument typesfree()
an invalid pointerUndefined Behaviour can manifest itself by a "segmentation fault", but that is by no means a required outcome. Anything could have happened :)