Точно, на что это походит, предполагая, что Вы привыкли к сокращенному пути, которым C и UNIX присваивают слова, это строки дубликатов :-)
Учет это - на самом деле не часть самого стандарта ISO C <глоток> (a) глоток> (это - вещь POSIX), это эффективно делает то же как следующий код:
char *strdup(const char *src) {
char *dst = malloc(strlen (src) + 1); // Space for length plus nul
if (dst == NULL) return NULL; // No memory
strcpy(dst, src); // Copy the characters
return dst; // Return the new string
}
, Другими словами:
Это пытается выделить достаточно памяти для содержания старой строки (плюс '\0' символов для маркировки конца строки).
, Если выделение перестало работать, оно устанавливает errno
на ENOMEM
и возвраты NULL
сразу. Установка errno
к ENOMEM
, что-то malloc
делает в POSIX, таким образом, мы не должны явно делать этого в нашем strdup
. Если Вы не совместимый POSIX, ISO C на самом деле не передает под мандат существование [1 110], таким образом, я не включал это здесь <глоток> (b) глоток>.
Иначе выделение работало так, мы копируем старую строку в новую строку <глоток> (c) глоток> и возвращаем новый адрес (который вызывающая сторона ответственна за освобождение в какой-то момент).
Имеют в виду, что это - концептуальное определение. Любой писатель библиотеки, стоящий их зарплаты, возможно, обеспечил в большой степени оптимизированный код, предназначающийся для конкретного используемого процессора.
<час><глоток> (a) глоток> Однако функционирует, начиная с [1 111], и строчная буква резервируются стандартом для будущих направлений. От [1 112]:
Каждый заголовок объявляет или определяет все идентификаторы, перечисленные в его связанном подпункте, и *дополнительно объявляет или определяет идентификаторы, перечисленные в его связанном будущем подпункте направлений библиотеки. **
будущие направления для [1 113] могут быть найдены в [1 114]:
Имена функций, которые начинаются
str
,mem
, илиwcs
и строчная буква, могут быть добавлены к объявлениям в<string.h>
заголовок.
, Таким образом, необходимо, вероятно, назвать его чем-то еще, если Вы хотите быть в безопасности.
<час> <глоток> (b) глоток> изменение в основном заменило бы if (d == NULL) return NULL;
:
if (d == NULL) {
errno = ENOMEM;
return NULL;
}
<час> <глоток> (c) глоток> Примечание, которое я использую strcpy
, для которого, так как это ясно показывает намерение. В некоторых реализациях это может быть быстрее (так как Вы уже знаете длину) использовать memcpy
, поскольку они могут допускать передачу данных в больших блоках, или параллельно. Или это не может:-), молитва Оптимизации № 1: "измерьте, не угадывайте".
В любом случае, должен Вы решать пойти тем путем, Вы сделали бы что-то как:
char *strdup(const char *src) {
size_t len = strlen(src) + 1; // String plus '\0'
char *dst = malloc(len); // Allocate space
if (dst == NULL) return NULL; // No memory
memcpy (dst, src, len); // Copy the block
return dst; // Return the new string
}
Никакой смысл повторяющий другие ответы, но обратите внимание на то, что strdup()
не может сделать ничего, что это хочет от перспективы C, так как это не часть никакого стандарта C. Это однако определяется POSIX.1-2001.
От strdup человек :
Эти strdup()
функция должна возвратить указатель на новую строку, которая является дубликатом строки, на которую указывают s1
. Возвращенный указатель может быть передан free()
. Нулевой указатель возвращается, если новая строка не может быть создана.
Это делает дубликат строки переданным в путем выполнения malloc и , strcpy строки передал в. Буфер malloc'ed возвращается вызывающей стороне, следовательно потребность работать свободный на возвращаемом значении.
Самая ценная вещь, которую это делает, дают Вам другую строку, идентичную первому, не требуя, чтобы Вы выделили память (местоположение и размер) сами. Но, как отмечено, все еще необходимо освободить его (но который не требует вычисления количества, также.)
char * strdup(const char * s)
{
size_t len = 1+strlen(s);
char *p = malloc(len);
return p ? memcpy(p, s, len) : NULL;
}
Возможно, код немного быстрее, чем с strcpy ()
, поскольку символ \ 0
не нужно искать снова (он уже был с strlen ()
).