strdup()
C 에서 함수 의 목적은 무엇입니까 ?
strdupa
strlen
매우 작고 이미 결정하지 않은 한 위험합니다 . 그러나 스택에서 고정 크기 배열을 사용할 수 있습니다.
strdup
/ strdupa
의미는 무엇입니까 ?
strdup()
C 에서 함수 의 목적은 무엇입니까 ?
strdupa
strlen
매우 작고 이미 결정하지 않은 한 위험합니다 . 그러나 스택에서 고정 크기 배열을 사용할 수 있습니다.
strdup
/ strdupa
의미는 무엇입니까 ?
답변:
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는 실제로 존재를 요구하지 않으므로 ENOMEM
여기에 포함시키지 않았습니다 (b) .
그렇지 않으면 할당이 작동하여 이전 문자열을 새 문자열 (c)에 복사하고 새 주소 (호출자가 어떤 시점에서 해제해야 함 ) 를 반환합니다.
그것이 개념적인 정의라는 것을 명심하십시오. 급여를받을 가치가있는 모든 라이브러리 작성자는 사용중인 특정 프로세서를 대상으로 최적화 된 코드를 제공했을 수 있습니다.
(a) 단, str
소문자로 시작하는 기능 은 향후 지침을 위해 표준으로 예약되어 있습니다. 보낸 사람 C11 7.1.3 Reserved identifiers
:
각 헤더는 관련 하위 조항에 나열된 모든 식별자를 선언 또는 정의하고 * 선택적으로 관련 미래 라이브러리 지침 하위 조항에 나열된 식별자를 선언 또는 정의합니다. **
향후 방향은 다음에서 string.h
확인할 수 있습니다 C11 7.31.13 String handling <string.h>
.
로 시작하는 함수 이름
str
,mem
또는wcs
와 소문자 편지는의 선언에 추가 할 수있다<string.h>
헤더.
따라서 안전을 원한다면 다른 것으로 부를 것입니다.
(b) 변경 사항은 기본적으로 다음으로 대체 if (d == NULL) return NULL;
됩니다.
if (d == NULL) {
errno = ENOMEM;
return NULL;
}
(씨) 내가 사용하는 것에 주목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
은 문자열 복사본에 힙 메모리를 할당하려는 상황을위한 것입니다. 그렇지 않으면 스스로해야합니다. 이미 충분히 큰 버퍼 (malloc'ed 또는 기타)를 가지고 있다면을 사용하십시오 strcpy
.
{ EDOM, EILSEQ, ERANGE }
는 필요한 오류 코드 로만 요구됩니다 . 이에 대한 답변을 업데이트했습니다.
char * strdup(const char * s)
{
size_t len = 1+strlen(s);
char *p = malloc(len);
return p ? memcpy(p, s, len) : NULL;
}
아마 코드가 조금 더 빨리와보다 strcpy()
는 AS \0
문자가 (이미와 있었다 다시 검색 할 필요가 없습니다 strlen()
).
return memcpy(malloc(len), s, len);
보다는 할당 충돌이 더 NULL
낫습니다.
NULL
충돌하지 않는다; 정의되지 않았습니다. 충돌하는지 확인하려면 실패한 emalloc
호출 abort
을 작성하십시오 .
emalloc
다른 플랫폼에서 코드를 작성할 때 나중에 사용할 수 있도록 Solaris 또는 Linux에서 필요하지 않더라도 사용하는 습관을 가지십시오 .
다른 답변을 반복 strdup()
해도 아무런 의미가 없지만 C 표준의 일부가 아니므로 C 관점에서 원하는 모든 것을 할 수 있습니다. 그러나 POSIX.1-2001에 의해 정의됩니다.
strdup()
휴대용? POSIX 이외의 환경에서는 사용할 수 없습니다 (어쨌든 구현 가능). 그러나 POSIX 함수가 무엇이든 할 수 있다고 말하는 것은 상당히 비현실적입니다. POSIX는 C만큼 우수하고 더 대중적인 또 다른 표준 입니다.
strdup
확장 기능을 제공 할 수 있다고 생각합니다 . 이러한 구현에서는 strdup
POSIX 함수와 동일한 방식으로 작동 한다고 보장 할 수 없습니다 . 이러한 구현에 대해서는 잘 모르지만 합법적 인 비 악성 구현은 char *strdup(char *)
역사적인 이유로 제공 할 수 있으며에 대한 전달 시도를 거부 할 수 const char *
있습니다.
에서 에서는 StrDup 사람 :
이 strdup()
함수는로 가리키는 문자열의 복제 본인 새 문자열에 대한 포인터를 반환해야합니다 s1
. 반환 된 포인터는에 전달 될 수 있습니다 free()
. 새 문자열을 작성할 수 없으면 널 포인터가 리턴됩니다.
strdup ()은 종료 문자 '\ 0'을 포함하여 문자 배열에 대한 동적 메모리 할당을 수행하고 힙 메모리의 주소를 리턴합니다.
char *strdup (const char *s)
{
char *p = malloc (strlen (s) + 1); // allocate memory
if (p != NULL)
strcpy (p,s); // copy string
return p; // return the memory
}
따라서 메모리를 할당하지 않고도 인수가 제공 한 문자열과 동일한 문자열을 제공합니다. 그러나 나중에도 여전히 해제해야합니다.
strdup
strndup
POSIX 호환 시스템에서 다음 과 같이 정의됩니다.
char *strdup(const char *str);
char *strndup(const char *str, size_t len);
에서는 StrDup () 함수는 문자열의 사본을위한 충분한 메모리를 할당하고 str
, 그것을 복사, 반환 포인터를 않습니다.
포인터는 이후 함수에 대한 인수로 사용될 수 있습니다 free
.
사용 가능한 메모리가 충분하지 않으면를 NULL
반환하고 errno
로 설정하십시오
ENOMEM
.
strndup () 대부분의 기능을 복사 len
문자열의 문자는 str
항상 복사 된 문자열을 종료 널 (null).
진술 :
strcpy(ptr2, ptr1);
(이것이 포인터를 변경한다는 사실을 제외하고)와 같습니다.
while(*ptr2++ = *ptr1++);
이므로:
ptr2 = strdup(ptr1);
다음과 같습니다.
ptr2 = malloc(strlen(ptr1) + 1);
if (ptr2 != NULL) strcpy(ptr2, ptr1);
따라서 복사 한 문자열을 다른 함수에서 사용하려면 (힙 섹션에서 생성됨)을 사용할 수 있습니다 strdup
. 그렇지 않으면 strcpy
충분합니다.