본문 바로가기
Study/C언어

C언어 - 배열과 스택, 버퍼 오버플로우

by 멘탈은안녕하신가 2020. 6. 3.
728x90
반응형
  • 배열과 스택은 밀접한 관계가 있다.
  • 스택은 쌓이는 같은 이미지를 떠올리지만 사실 배열로 구성되어 있다.
  • 어떻게 구성되어 있는지 아래 코드와 설명을 보며 이해하자.
    • 코드
#include <stdio.h>

int main()
{
                char ch1[2];
                char ch2[2];
                char ch3[2];

                printf( "문자 입력\n" );
                
                /*scanf의 오류때문에 scanf_s를 쓰는경우엔 'scanf_s("%s",ch1,버퍼의 크기);'와 같이 3개의 인자를 넣어주어야 한다.
                '_s'가 오버플로우 현상을 잡기위해 만든것이므로 _s에선 오류가 발생하지 않는다.*/
                scanf( "%s", ch1);
                
                //scanf_s와 같이 _s를 쓰는 연산자는 설정에서 sdl체크를 해제해주면 _s없이 사용 할 수 있다.
                scanf( "%s", ch2);

                scanf( "%s", ch3);

                printf( "ch1 : %s size : %d\n", ch1, sizeof (ch1));
                printf( "ch2 : %s size : %d\n", ch2, sizeof (ch2));
                printf( "ch3 : %s size : %d\n", ch3, sizeof (ch3));

                 return 0;
}

 

    • 입력
      • abcd(엔터)
      • 1234(엔터)
      • qwer(엔터)
    • 출력

ch1 :           size : 2

ch2 : er       size : 2

ch3 : qwer   size : 2

 

    • 길이가 2 이니까 ch1 ab, ch2 12, ch3 qw 나와야 하는것 아닌가? 하고 생각했을 있다.
    • 출력 결과에서 ch1에 공백, ch2에 'er'이 출력되고 ch1의 size에 '2'가 나오는 것일까?


1. ch1, ch2, ch3
선언하면 메모리 스택에는 다음과 같은 형태로 할당이 된다.

 

그림 1

2. c에서 문자열은 '마지막에 NULL(=0)을 포함하는 char형식의 배열'이다.


3. (배열은
포인터이다.), 입력받으면 해당위치( ex) ch1[0])부터 한 글자씩 입력 되며 마지막에 0(NULL)이 들어간다. 그런데 각 공간은 2글자인데 입력받는 문자열은 4글자(NULL포함 5글자)가 되어 다른 배열의 영역을 침범해 덮어쓴다.

아래 그림은 모든 입력이 끝난 후의 최종형태이다.

 

그림 2

4. 문자열출력은 '포인터의 해당위치에서 시작해 NULL을 만날때까지 출력'으로 이루어진다. 여기서 배열이름이 포인터 역할을 하고 출력은 아래와 같다.

     ch1[0]부터 NULL까지 => 처음부터 NULL이 나오기 때문에 출력이 없다.

     ch2[0]부터 NULL까지 => 'er' 출력

     ch3[0]부터 NULL까지 => 'qwer' 출력

 

  • 스택과 배열로 나누어진게 이해가 가지 않는다면 아래 메모리 영역으로만 설명한 내용을 보자.

 

728x90
반응형

댓글