-1

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

alexparkjw
  • 113
  • 1
  • 6
  • 6
    Please read [Why not upload images of code on SO when asking a question?](https://meta.stackoverflow.com/questions/285551/why-not-upload-images-of-code-on-so-when-asking-a-question) – Amadan Jan 17 '20 at 07:18
  • And please change the font type :) – EUS Jan 17 '20 at 07:50
  • That is a free font, – alexparkjw Jan 17 '20 at 08:07
  • 1
    While you shouldn't post images of code, you should post a [mcve]. The problem is in the code you *don't* show. – Some programmer dude Jan 17 '20 at 08:26
  • What you do in the code you don't show leads to *undefined behavior*, which makes your whole program wrong. The problem have nothing to do with the differences between using pointers to string literals, or pointers to dynamically allocated strings. Undefined behavior is undefined, anything could happen (including summoning [nasal demons](http://www.catb.org/jargon/html/N/nasal-demons.html)). – Some programmer dude Jan 17 '20 at 08:59

1 Answers1

5

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.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Thank you. In the example, why do those behavior differently – alexparkjw Jan 17 '20 at 07:38
  • @alexparkjw I know the problem, but you need to include a [mcve] in your question. Take the code you showed in the images, and copy-paste it *as text* into the question. – Some programmer dude Jan 17 '20 at 08:41
  • https://github.com/alexparkjw/typing/blob/master/pa2.c , src code in git, thank you – alexparkjw Jan 17 '20 at 08:43
  • 1
    @alexparkjw And what happens after you fix the bug? Then the code in the link will not behave wrongly and your question (and all answers) becomes worthless. Remember that this site isn't only to help you right now, but also to help people in the future which have the same or similar problems to you. That's why you need to make questions *self-contained*, which means you need to include the code in the question itself. – Some programmer dude Jan 17 '20 at 08:49
  • I don't want to fix the problem witch I already know how to fix it. However, I wanna know curious behavior with pointer that is all.... – alexparkjw Jan 17 '20 at 08:55
  • 4
    Detail: "Literal strings in C can't be modified" is more like "Literal strings in C should not be modified". To attempt to modify is UB - it might "work:, it might not, might crash, etc. – chux - Reinstate Monica Jan 17 '20 at 15:00