В C все строковые литералы на самом деле являются массивами (эффективно только для чтения) символов.
С
char *str = "kiwi";
вы указываете str
на первый элемент такого массив.
Это несколько эквивалентно
char internal_array_for_kiwi[5] = { 'k', 'i', 'w', 'i', '\0' };
char *str = &internal_array_for_kiwi[0];
Функция strdup
динамически распределяет память и копирует переданную строку в эту память, создавая копию строки.
Таким образом, после
char *str = strdup("kiwi");
у вас будет два массива, содержащих одинаковое содержимое.
Это эквивалентно
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);
Необходимо подчеркнуть важное различие между ними: буквенные строки в C не могут быть изменены. Попытка изменить такую строку приведет к неопределенному поведению . Массивы не const
, но фактически доступны только для чтения.
Если вы создаете свой собственный массив (в виде массива или динамически распределяется), то вы можете изменять его содержимое столько раз, сколько хотите. так как вы не go выходите за пределы или не изменяете строку с нулевым терминатором.
Так что, если у нас есть
char *str1 = "kiwi";
char *str2 = strdup("kiwi");
, тогда
str1[0] = 'l'; // Undefined behavior, attempting to modify a literal string
str2[0] = 'l'; // Valid, strdup returns memory you can modify
Потому что буквально Строки не могут быть изменены, рекомендуется использовать const char *
при указании на них:
const char *str1 = "kiwi";
Еще одна важная вещь, которую следует помнить: так как strdup
выделяет память динамически (используя malloc
), вам нужно free
этой памяти, как только вы закончите со строкой:
free(str2);
Если вы не освободите память, у вас будет утечка памяти.
Beyond выше, нет никакой эффективной разницы между этими двумя вариантами. Оба могут использоваться взаимозаменяемо при вызове функций, например.