Strcpy vs strdup

Я читал, что strcpy предназначен для копирования строки, а strdup возвращает указатель на новую строку для дублирования строки.

Не могли бы вы объяснить, какие случаи вы предпочитаете использовать strcpy и какие случаи вы предпочитаете использовать strdup?

Ответ 1

strcpy(ptr2, ptr1) эквивалентно while(*ptr2++ = *ptr1++)

где as strdup эквивалентно

ptr2 = malloc(strlen(ptr1)+1);
strcpy(ptr2,ptr1);

(версия memcpy может быть более эффективной)

Итак, если вы хотите, чтобы строка, которую вы скопировали, использовалась в другой функции (поскольку она создана в разделе кучи), вы можете использовать strdup, иначе strcpy достаточно.

Ответ 2

Функции strcpy и strncpy являются частью стандартной библиотеки C и работают с существующей памятью. То есть вы должны предоставить память, в которой функции копируют строковые данные, а в качестве следствия вы должны иметь свои собственные способы узнать, сколько памяти вам нужно.

В зависимости от константы, strdup является функцией Posix и выполняет динамическое распределение памяти для вас. Он возвращает указатель на недавно выделенную память, в которую он скопировал строку. Но вы теперь отвечаете за эту память и должны в конечном итоге free ее.

Это делает strdup одной из "скрытых malloc" функций удобства, и это, по-видимому, также, почему оно не является частью стандартной библиотеки. До тех пор, пока вы используете стандартную библиотеку, вы знаете, что вы должны называть free для каждого malloc/calloc. Но такие функции, как strdup, вводят скрытый malloc, и вы должны рассматривать его так же, как malloc для управления памятью. (Другие такие скрытые функции выделения - GCC abi::__cxa_demangle().) Остерегайтесь!

Ответ 3

strdup выделяет память для новой строки в куче, при использовании strcpy (или более безопасного strncpy varient) я могу скопировать строку в предварительно выделенную память на либо кучу или стек.

Ответ 4

В принятом ответе реализация strdup представлена ​​в виде:

ptr2 = malloc(strlen(ptr1)+1);
strcpy(ptr2,ptr1);

Однако это несколько неоптимально, потому что как strlen, так и strcpy нужно найти длину строки, проверив, является ли каждый символ \0.

Использование memcpy должно быть более эффективным:

char *strdup(const char *src) {
    size_t len = strlen(src) + 1;
    char *s = malloc(len);
    if (s == NULL)
        return NULL;
    return (char *)memcpy(s, src, len);
}

Ответ 5

char *strdup(char *pszSrch);

strdup будет выделять размер памяти исходной строки. Если распределение хранилища выполнено успешно, исходная строка копируется в дублируемую строку.

strdup d return NULL при сбое. Если память не выделена, копирование завершается с ошибкой strdup return NULL.