2010-09-21 3 views
2

Я хочу, чтобы иметь четкое представление о всех преимуществах/недостатках следующий код:Преимущества и недостатки использования strdup на строковый литерал

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

str1:

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

str2:

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

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

+5

Ни преимущество, ни недостаток, но 'str2' должен почти наверняка будет объявлен 'const char *'. И если вы хотите модифицируемую короткую строку, 'char str1 [] =" some string ";' хорошо. –

ответ

1

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

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

3

Используйте ни, если вы можете и избежать его одним из следующей

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

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

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

+0

Что касается 'str3': строковый литерал имеет тип' char [] '. Какой смысл копировать его в объект типа 'const char []' (и статический четный)? Я думаю, что было бы лучше просто определить указатель на литерал и избежать копирования: 'const char * str3 =" some string ";' – pmg

+0

'str4' имел очень расточительные накладные расходы.Каждый раз, когда вводится область 'str4', программа выполняет эквивалент' strcpy (str4, "some string"); '. –

+0

@R .: нет не совсем. Длина обоих массивов 'char' фиксируется во время компиляции. Таким образом, в основном это «memcpy» из постоянного адреса в стек. По сравнению с методом 'str1' он сохраняет' malloc' за кулисами и 'free', что нужно что-то делать. Я думаю, это все, что я сказал. –

0
  1. strdup не C89 и C99 не -> не ANSI C -> не переносим
  2. является портативным и str2 подразумевается Const