HOWTO · C

C에서 strdup 함수 사용

strdup가 C에서 문자열을 복제하는 방식, 할당된 복사본을 확인하고 해제하는 방법, 그리고 strndup나 GNU strdupa를 사용해야 하는 경우를 알아봅니다.

이 페이지의 내용

strdup는 C 문자열을 널 종료 문자열로 복사해 별도로 할당된 메모리를 반환합니다. 반환된 포인터를 사용하기 전에 확인하고, 복사에 성공했다면 free로 해제하세요. 복사할 바이트 수를 제한해야 한다면 strndup를 사용하세요. strdupa는 수명이 다른 GNU 전용 대안입니다.

strdup의 기능과 사용 가능 환경

strdup의 선언은 <string.h>에 있는 char *strdup(const char *s);입니다. 널 종료 문자열 s의 바이트를 끝의 널 바이트까지 새로 할당한 저장 공간에 복사합니다. 반환된 포인터는 그 저장 공간을 가리키며, 할당에 실패하면 함수는 NULL을 반환합니다.

strdup는 C 표준 라이브러리에 포함되지 않습니다. POSIX에서 규정한 함수이며 GNU C 라이브러리 같은 일반적인 C 라이브러리에서 제공합니다. 엄격한 언어 모드로 컴파일할 때 선언을 노출하려면 플랫폼에 따라 기능 테스트 매크로가 필요할 수 있습니다. POSIX 시스템 이외의 환경까지 이식성을 고려한다면 대상 플랫폼의 문서를 확인하세요.

strdup로 문자열 복제하기

플랫폼에서 POSIX 선언을 노출할 때 _POSIX_C_SOURCE를 사용한다면 헤더를 포함하기 전에 정의하세요. 이 예제는 결과를 읽기 전에 확인하고 사용이 끝난 복사본을 해제합니다. 실행이 성공하면 원본과 복사본을 출력합니다.

다음 예제를 실행하세요:

#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    const char *source = "C strings";
    char *copy = strdup(source);

    if (copy == NULL) {
        puts("Could not duplicate the string.");
        return EXIT_FAILURE;
    }

    printf("Source: %s\nCopy: %s\n", source, copy);
    free(copy);
    return 0;
}
Source: C strings
Copy: C strings

strdup가 NULL을 반환하면 해당 포인터를 문자열 함수에 전달하거나 free를 호출하지 마세요. 위 예제의 실패 분기는 문제를 알리고 정상적으로 종료합니다. 복사본이 더는 필요하지 않을 때 free를 정확히 한 번 호출하세요. 원본 문자열 리터럴을 해제하거나 해제한 뒤 복사본을 사용하는 것은 올바르지 않습니다.

strndup로 최대 n바이트 복사하기

strndup도 POSIX에서 규정하며 <string.h>에 선언되어 있습니다. 선언은 char *strndup(const char *s, size_t n);입니다. s에서 최대 n바이트를 복사하고, 할당된 결과 끝에는 항상 널 바이트를 추가합니다. 제한값은 문자가 아니라 바이트 수를 나타내므로, 다중 바이트 인코딩 문자 안에서 제한에 걸리면 문자가 중간에서 잘릴 수 있습니다.

예를 들어 strndup("C strings", 3)은 "C s" 문자열을 만듭니다. 반환된 저장 공간은 동적으로 할당되므로 strdup와 마찬가지로 NULL인지 확인하고, 성공한 결과는 free로 해제하세요. 제한값은 복사량을 정할 뿐 결과의 수명이나 소유권을 바꾸지 않습니다.

GNU 전용 strdupa 대안 이해하기

strdupa는 GNU C 라이브러리 확장이며 POSIX 함수도 C 표준 함수도 아닙니다. 선언을 노출하려면 필요에 따라 시스템 헤더보다 먼저 _GNU_SOURCE를 정의하세요. strdup처럼 널 종료 문자열을 받아 복사본을 만들지만, 힙 메모리를 반환하는 대신 현재 함수에 연결된 자동 저장 공간을 사용합니다.

이 저장 공간은 이를 포함하는 함수가 실행 중인 동안에만 유효합니다. 함수가 끝난 뒤에도 사용하도록 포인터를 반환하지 말고, 그 포인터에 free를 호출하지 마세요. 사용 가능 여부와 구현은 GNU 환경에 따라 다르므로 POSIX 인터페이스가 필요하거나 free로 수명을 관리할 복사본이 필요하다면 strdup를 사용하세요. strdupa는 GNU 환경에 한정되므로 여기서는 실행 예제로 보여 주지 않습니다.