본문 바로가기

C언어

Chapter 7. strcpy()의 비밀

Chapter 7.strcpy()의 비밀

7_1.c

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

main()
{
//char *imsip;
char imsi[10];

//strcpy(imsip, "archie");

strcpy(imsi, "archie");

puts(imsip);
}

gcc -o 7_1 7_1.c
./7_1
//세그멘테이션 오류

archie

포인터변수로 선언된 imsip에 strcpy()를 이용하여 문자열을 할당할 경우 위와같이 메모리참조 에류가 발생한다.

배열을 이용한strcpy()

strcpy(imsi, "archie");

배열로 선언된imsi에 strycpy()를 이용하여 문자열을 할당하는 경우 각각의 배열요소에 문자열의 각 문자 하나씩 할당된다.

imsi[0] = 'a', imsi[1] = 'r' imsi[2] = 'c', imsi[3] = 'h', imsi[4] = 'i', imsi[5] = 'e'

포인터 변수를 이용한 strcpy()

char *imsip;

strcpy(imsip, "archie");

포인터변수로 선언된 imsip에 strycpy()를 이용하여 문자열을 할당하는 경우

strcpy()의 첫번째 인자로 imsip가 생성되면서 할당된쓰레기 주소 값이 전달되고 두번째 인자로는문자열"archie"의문자 'a'의 주소 값이 전달된다.

따라서, 쓰레기값이 할당되어 있는 곳(시스템에서 사용중인 메모리 영역일 확률이 크다)에 문자열을복사하라는 명령어는 메모리참조 에러가 발생하게 된다.

그렇다면 포인터 변수 imsip에 임의의 주소값을 할당한 후 strcpy() 함수를 사용한다면 정상적인 결과 값을 얻을 수 있을 것이다.

7_3.c

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

main()
{
int imsi;
char *imsip;

imsi = 0x8047d240;
imsip = (char *)imsi;

strcpy(imsip, "archie");
printf(imsip);
}

gcc-o 7_3 7_3.c

./7_3

archie

imsip는 주소 값 이외에는 절대 할당될 수 없다.

imsi에 들어 있는 값 자체를 강제로 "주소화"하여 imsip에 할당 하였다.(캐스트 연산)

배열과 malloc()을 이용한 번지 할당

7_4.c

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

main()
{
char dim[10];
char *imsip;

imsip = dim;

strcpy(imsip, "archie");

puts(imsip);
}

gcc -o7_47_4.c

./7_4

archie

"archie"가 복사되는 위치는 imsip가 가리키고 있는 곳이며imsip가 가리키는 곳은dim이므로 잘 수행된다.

하지만, imsip에 저장될 문자열이NULL 문자를 제외하고 9byte 이상 사용하지말아야 한다.

만약, NULL문자가 저장될 위치까지 문자를 채워 넣게 되면NULL 종료 문자를 만날때까지 이상한문자들이 출력될 것이다.

위의 문제점을 보안여 아래와 같은 방식으로 사용해야 된다.

7_5.c

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

main()
{
char *imsip;

imsip = (char *)malloc(sizeof(char) * 10);

strcpy(imsip, "archie string");

puts(imsip);
}

gcc -o 7_5 7_5.c

./7_5

archie string

imsip를 정의했을 때 저장되어 있는 값은 쓰레기 주소 값이다.

하지만, malloc()을 통해 안전한 주소 값을 할당 받았기 때문에 위처럼 문자열을 복사하여 넣어도 이상 없이 해당 문자열이 잘 출력된다.

문자열 포인터 변수를 정의한 후에는 항상 초기화에 신경쓰도록 하자.