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
.