본문 바로가기
Study/C언어

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

by 멘탈은안녕하신가 2018. 12. 17.
728x90
반응형
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
 
int main()
 
    char ch1[2];
    char ch2[2];
    char ch3[2];
 
    printf"문자 입력\n" );
 
    scanf"%s", ch1); // scanf의 오류때문에 scanf_s를 쓰는경우엔 'scanf_s("%s",ch1,버퍼의 크기);'와 같이 3개의 인자를 넣어주어야 한다. - _s가 오버플로우 현상을 잡기위해 만든것이므로 _s에선 오류가 발생하지 않는다.
    scanf"%s", ch2); // scanf_s와 같이 _s를 쓰는 연산자는 설정에서 sdl체크를 해제해주면 _s없이 사용 할 수 있다.
    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;
 
}
cs

 

  • 입력

    abcd
    1234
    qwer

 

  • 출력결과
    ch1 :           size : 2
    ch2 : er        size : 2
    ch3 : qwer     size : 2

 

  • 출력결과에서 ch1에 공백, ch2에 'er', size가 2가 나오는 이유는?
1. ch1, ch2, ch3을 선언하면 메모리 스택에는 다음과 같은 형태로 할당이 된다.
 

 

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

 

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

 

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

 

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

 

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

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

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

 

 

좀 더 쉽게 아래 그림을 보자.

 

 

 

열심히 그려보았다. 하핫

728x90
반응형

댓글