C 언어 기초

void save(const char *input) {
    char name[8];
    strcpy(name, input);
    printf("%s\n", name);
}

위의 함수 save에 8문자의 문자열 "ABCDEFGH"를 전달했다. 일어나는 일로 올바른 것은?

  1. A종단의 '\0'을 포함하여 9바이트가 쓰여, name 바깥의 1바이트를 망가뜨린다(미정의 동작)
  2. B정확히 8문자이므로 name에 들어가며, ABCDEFGH가 올바르게 표시된다
  3. Cstrcpy가 name의 크기에 맞춰 7문자로 잘라 내고, 마지막 요소에 종단의 '\0'을 넣는다
정답과 해설 보기

정답: A. 종단의 '\0'을 포함하여 9바이트가 쓰여, name 바깥의 1바이트를 망가뜨린다(미정의 동작)

문자열 "ABCDEFGH"는 종단의 '\0'을 포함하면 9바이트입니다. strcpy는 쓰기 대상의 크기를 모른 채 '\0'까지를 모두 복사하므로, 8바이트인 name의 바깥으로 1바이트 넘쳐서 씁니다(버퍼 오버플로). 넘친 부분은 스택 위의 다른 변수나 복귀 주소를 망가뜨리기도 하며, 외부에서 긴 입력을 주어 임의의 코드를 실행시키는 공격에도 사용됩니다. snprintf(name, sizeof name, "%s", input)처럼 쓰는 크기를 지정할 수 있는 함수를 사용하여 막습니다.

이 분야 연습하기 분야로 돌아가기

C 언어 기초의 다른 문제

  1. C 언어에서 NULL 포인터를 참조했을(p가 NULL일 때 *p를 읽었을) 때의 설명으로 올바른 것은?
  2. char는 1바이트, int는 4바이트이며, int를 4의 배수 주소에 맞춰 두는 일반적인 환경으로 한다. 위의 코드를 실행했을 때의 출력으로 올바른 것은?
  3. uint32_t는 32비트, uint8_t는 8비트의 부호 없는 정수형이며, 리틀 엔디언 환경으로 한다. 위의 코드를 실행했을 때의 출력으로 올바른 것은?
  4. 3비트의 비트 필드에 9를 넣는 위의 코드를 실행했을 때의 출력으로 올바른 것은?
  5. #define으로 정의한 매크로 SQUARE를 사용하는 위의 코드를 실행했을 때의 출력으로 올바른 것은?