Преимущества и недостатки использования strdup для строкового литерала - PullRequest
2 голосов
/ 21 сентября 2010

Я хочу прояснить все преимущества / недостатки следующего кода:

{
    char *str1 = strdup("some string");
    char *str2 = "some string";
    free(str1);
}

str1:

  • Вы можете изменить содержимое строки

str2:

  • Вам не нужно использовать free ()
  • Быстрее

Есть ли другие различия?

Ответы [ 3 ]

3 голосов
/ 21 сентября 2010

Не используйте ни один, если можете, и избегайте этого одним из следующих

static char const str3[] = { "some string" };
char str4[] = { "some string" };

str3, если вы никогда не планируете его изменять, и str4, если вы это делаете.

str3 гарантирует, что никакая другая функция в вашей программе не сможет изменить вашу строку (строковые литералы могут совместно использоваться и изменяемые). str4 выделяет массив постоянного размера в стеке, поэтому распределение и освобождение происходит без дополнительных затрат. Система должна просто скопировать ваши данные.

2 голосов
/ 21 сентября 2010

Использование исходной строки - будь то литерал в источнике, часть файла с отображением в памяти или даже выделенная строка, «принадлежащая» другой части вашей программы - имеет преимущество в экономии памяти и, возможно, устранении уродливости условия ошибки, которые в противном случае вам пришлось бы обрабатывать, если вы выполнили распределение (что может привести к сбою). Недостаток, конечно, заключается в том, что вы должны отслеживать тот факт, что эта строка не «принадлежит» коду, использующему ее в настоящее время, и, следовательно, она не может быть изменена / освобождена. Иногда это означает, что вам нужен флаг в структуре, чтобы указать, была ли выделена используемая строка для структуры или нет. В небольших программах это может означать, что вы должны вручную следовать логике владения строк через несколько функций и убедиться, что это правильно.

Кстати, если строка будет использоваться структурой, один хороший способ обойти необходимость держать флаг, отмечающий, был ли он выделен для структуры или нет, состоит в том, чтобы выделить место для структуры и строки. (при необходимости) с одним вызовом на malloc. Затем освобождение структуры всегда работает, независимо от того, была ли строка выделена для структуры или назначена из строкового литерала или другого источника.

0 голосов
/ 21 сентября 2010
  1. strdup не C89 и не C99 -> не ANSI C -> не переносимый
  2. является переносимым, а str2 является неявным const
...