What is the difference between
char *key_str="kiwi";
and
char *key_str = strdup("kiwi");
For example:
int strCmp(void *vp1, void *vp2) {
char * s1 = (char *) vp1;
char * s2 = (char *) vp2;
return strcmp(s1, s2);
}
Why do those *key_str
behave differently when used in the function strCmp()
?
src code : https://github.com/alexparkjw/typing/blob/master/pa2.c
In C all literal strings are really arrays of (effectively read-only) characters.
With
char *str = "kiwi";
you make str
point to the first element of such an array.
It is somewhat equivalent to
char internal_array_for_kiwi[5] = { 'k', 'i', 'w', 'i', '\0' };
char *str = &internal_array_for_kiwi[0];
The strdup
function dynamically allocates memory and copies the passed string into this memory, creating a copy of the string.
So after
char *str = strdup("kiwi");
you have two arrays containing the same contents.
It's equivalent to
char internal_array_for_kiwi[5] = { 'k', 'i', 'w', 'i', '\0' };
char *str = malloc(strlen(internal_array_for_kiwi) + 1);
strcpy(str, internal_array_for_kiwi);
An important difference between the two needs to be emphasized: Literal strings in C can't be modified. Attempting to modify such a string will lead to undefined behavior. The arrays aren't const
, but are effectively read-only.
If you create your own array (as an array or allocated dynamically) then you can modify its contents as much as you want, as long as you don't go out of bounds or change the string null-terminator.
So if we have
char *str1 = "kiwi";
char *str2 = strdup("kiwi");
then
str1[0] = 'l'; // Undefined behavior, attempting to modify a literal string
str2[0] = 'l'; // Valid, strdup returns memory you can modify
Because literal strings can't be modified, it's recommended that you use const char *
when pointing to them:
const char *str1 = "kiwi";
Another important thing to remember: Since strdup
allocates memory dynamically (using malloc
) you need to free
that memory once you're done with the string:
free(str2);
If you don't free the memory then you will have a memory leak.
Beyond the above, there's no effective difference between the two variants. Both can be used interchangeably when calling functions, for example.