C언어/string.h

[C언어] strcpy 함수 (문자열 복사, string copy)

아무일도없었다 2022. 9. 9. 22:35

사용범위

Windows, Unix 등 모든 OS에서 사용가능한 표준 API 함수

기능

C언어 표준 함수로 string 을 복사하는데 사용한다.
strcpy 함수에서 string 의 끝을 판단하는 기준은 NULL 문자이다. (\0)

헤더

#include <string.h>

※ 함수 사용시 string.h 파일을 include 하지 않는다면 컴파일시 error 발생 ※


함수

char* strcpy(char* dest, const char* source);

파라미터

  • char* dest
    • destination 의 약자로 복사한 문자열을 저장할 대상의 버퍼를 입력한다.
    • 반드시 유효한 주소값을 입력해야하고 유효하지 않은 주소 입력시 signal 이 발생한다. 
  •  const char* source
    • dest 에 복사할 문자열을 입력한다. (반드시 NULL로 종료되는 문자열을 입력해야한다.)
    • NULL 문자 (\0) 가 나올때까지 source 의 내용을 복사하며, NULL 문자까지 복사된다.
    • 반드시 유효한 주소값을 입력해야하고 유효하지 않은 주소 입력시 signal 이 발생한다.

반환값 (return)

복사된 string 의 주소값 (pointer) 를 반환한다. ( ret = char* dest )

잡학지식

strcpy 함수는 편리해서 많이 사용하지만 무방비로 사용하기에는 굉장히 위험한 함수다.

먼저 strcpy 는 string (char array) 에 접근하기 위해서 pointer 를 사용하여 주소에 접근한다.
그 과정에서 NULL pointer 에 접근하게 된다면 sigsegv 가 발생하고 프로그램이 종료되는 경우가 종종있다.
(이런 경우를 대비하기 위해서는 dest 와 source 의 주소값을 체크하는 습관을 가져야한다.)

 두번째로 strcpy 는 string 의 끝을 알아내는 방법으로 NULL 문자를(\0) 확인한다.
하지만 dest 에 입력되는 버퍼의 크기를 확인하지 않는다. dest 의 버퍼크기를 넘어가는 string 이 source 에 입력된다면 dest 의 크기만큼 짤라서 복사하는게 아니라 dest 의 크기를 넘어서 다른 영역의 주소값까지 string 을 복사하게 된다.
이러한 버그를 buffer overflow 라고 불리우며 이 내용은 이후 다른 포스팅에서 자세히 다룰 예정이다.

이러한 문제들을 보완하기 위해서 strncpy, strcpy_s 와 같은 함수들이 추가되었다.
strcpy 의 사용을 권장하지 않지만 정확한 범위내에서 올바르게 사용하는게 보장된다면 strcpy를 사용하는게 성능 측면에서 좋을수도 있다.
하지만 미래에 확장성과 코드 관리를 위해서는 strncpy 와 같이 그나마(?) 안전한 함수를 사용하는걸 추천한다.

 

<소스 코드>

#include <stdio.h>
#include <string.h>

int main() {
    char buffer1[8] = {0,};
    char buffer2[8] = {0,};
    int i;

    strcpy(buffer1, "ABCDE");
    strcpy(buffer2, "FGH");
    printf("buffer1[%s] buffer2[%s]\n", buffer1, buffer2);

    // return value = buffer1
    strcpy(buffer1, buffer2);

    printf("string copy (buffer1 <- buffer2) buffer1[%s]\n", buffer1);

    for(i=0; i<8; i++) {
        printf("buffer1[%d]:[%c]\n", i, buffer1[i]);
    }

    return 0;
}

 

※ 실행 결과

buffer1[ABCDE] buffer2[FGH]
string copy (buffer1 <- buffer2) buffer1[FGH]
buffer1[0]:[F]
buffer1[1]:[G]
buffer1[2]:[H]
buffer1[3]:[ ]
buffer1[4]:[E]
buffer1[5]:[ ]
buffer1[6]:[ ]
buffer1[7]:[ ]

(ABCDE 에서 FGH\0 4byte 가 ABCD 위치에 복사되고 그 뒤에 E 문자가 남은것을 확인할 수 있다.)

반응형