strdup () - что это делает в C?

297
задан Grijesh Chauhan 2 July 2013 в 05:20
поделиться

6 ответов

Точно, на что это походит, предполагая, что Вы привыкли к сокращенному пути, которым 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
}

, Другими словами:

  1. Это пытается выделить достаточно памяти для содержания старой строки (плюс '\0' символов для маркировки конца строки).

  2. , Если выделение перестало работать, оно устанавливает errno на ENOMEM и возвраты NULL сразу. Установка errno к ENOMEM, что-то malloc делает в POSIX, таким образом, мы не должны явно делать этого в нашем strdup. Если Вы не совместимый POSIX, ISO C на самом деле не передает под мандат существование [1 110], таким образом, я не включал это здесь <глоток> (b) .

  3. Иначе выделение работало так, мы копируем старую строку в новую строку <глоток> (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
}
360
ответ дан 17 revs, 2 users 99% 23 November 2019 в 01:32
поделиться

Никакой смысл повторяющий другие ответы, но обратите внимание на то, что strdup() не может сделать ничего, что это хочет от перспективы C, так как это не часть никакого стандарта C. Это однако определяется POSIX.1-2001.

51
ответ дан jotik 23 November 2019 в 01:32
поделиться

От strdup человек :

Эти strdup() функция должна возвратить указатель на новую строку, которая является дубликатом строки, на которую указывают s1. Возвращенный указатель может быть передан free(). Нулевой указатель возвращается, если новая строка не может быть создана.

17
ответ дан Grijesh Chauhan 23 November 2019 в 01:32
поделиться

Это делает дубликат строки переданным в путем выполнения malloc и , strcpy строки передал в. Буфер malloc'ed возвращается вызывающей стороне, следовательно потребность работать свободный на возвращаемом значении.

3
ответ дан jussij 23 November 2019 в 01:32
поделиться

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

1
ответ дан dkretz 23 November 2019 в 01:32
поделиться
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 () ).

85
ответ дан 23 November 2019 в 01:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: