[C] gets_s() 함수, 디버깅을 통한 메모리 구조 알아보기

ludvico el's avatar
May 05, 2024
[C] gets_s() 함수, 디버깅을 통한 메모리 구조 알아보기
작성일: 20240505 최근 수정일: 20240505
OS: Windows 10 Pro 22H2 64bit language: C ver: - IDE: Visual Studio 2022 Community

Table of contents

선행지식

  1. ‘Debug - Windows - Memory - Memory 1’을 통해 디버그 시 Memory 창을 띄울 수 있다.
    1. notion image
  1. Debugging 시 F10을 눌러 다음 line으로 Step over할 수 있다.
  1. Hexadecimal(16진수) 0x00은 ASCII Code로 null을 의미한다.
    1. notion image
  1. puts()null을 만날 때까지 array에서 character를 put한다.
 

해당 게시글에서 사용할 예제 코드는 다음과 같다.
#include <stdio.h> int main(void) { char szName[32] = { 0 }; //char 32개가 있는 array를 만들고 모두 0으로 채운다. printf("이름을 입력하세요: "); //printf()는 line break 없음 //gets_s(szName, sizeof(szName)); gets_s(szName, sizeof(szName)); printf("당신의 이름은 "); puts(szName); //puts()는 line break 있음 puts("입니다."); return 0; }
  1. line 5에서 F9를 눌러 Breakpoint를 설정한다.
line 5에 Breakpoints가 설정된 모습
line 5에 Breakpoints가 설정된 모습
  1. F5를 눌러 Debugging을 시작한다.
    1. 이때 line 5에 Breakpoint가 있으므로 line 5 실행 직전에 멈춘다.
  1. F10을 눌러 Step over하면 line5의 char szName[32] = { 0 };이 실행된다.
    1. 즉, szName에 저장된 Memory Address는 32 byte의 크기를 가지고 모두 0x00으로 채워지게 된다.
  1. 이를 확인하기 위해 Memory1 Address에 ‘szName’을 입력한다.
    1. → szName에 저장된 address를 보여준다.
      Memory 1 Address에 ‘szName’을 입력한다.
      Memory 1 Address에 ‘szName’을 입력한다.
      실제로는 szName에 저장된 hexadecimal의 address값(0x0000003A3DD1F838)에서의 메모리 값을 보여준다.
hexadecimal 한 자리는 4bit이므로 총 32byte 만큼이 0x00으로 채워진 것을 알 수 있다.
      실제로는 szName에 저장된 hexadecimal의 address값(0x0000003A3DD1F838)에서의 메모리 값을 보여준다. hexadecimal 한 자리는 4bit이므로 총 32byte 만큼이 0x00으로 채워진 것을 알 수 있다.
  1. F10을 두 번 누르면 line 9까지 실행하게 되고 gets_s(szName, sizeof(szName));로 인해 szName에 값을 입력받게 된다.
    1. gets_s(szName, sizeof(szName));
      gets_s(szName, sizeof(szName));
      이때 ‘david’라고 입력을 해보자.
      david라고 입력한다.
      david라고 입력한다.
  1. Memory 1 Address에서 방금까지 00 00 00 ..이던 메모리 주소에 보관된 값들이 변경된 것을 알 수 있다.
    1. Hexadecimal 64, 61, 76, 69의 ASCII code 값은 각각 d, a, v, i이다. 즉, 유저가 방금 입력한 값이다.
      Hexadecimal 64, 61, 76, 69의 ASCII code 값은 각각 d, a, v, i이다. 즉, 유저가 방금 입력한 값이다.
      이때 fe라는 값들이 있는데 이는 Extended ASCII Table에서 정의된 값으로 메모리 주소는 확보했지만 특정한 값이 할당되지 않은 주소 공간에 채워넣는 임의의 값이라고 생각하면 된다.
  1. F10을 두 번 누르면 console에 다음과 같이 출력된다.
    1. notion image
      이는 line 11의 puts(szName);에 의한 출력이다.
      puts(szName);szName에 보관된 Address로 이동하여 null(0x00)을 만날 때까지 메모리 주소에 보관된 값을 put한다.
      6.에서의 그림과 같이 해당 Address에는 0x64 0x61 0x76 0x69 0x64 0x00 0xfe …의 값들이 보관되어 있으므로 0x00을 만날 때까지의 값들을 put한다.
      따라서 console에 0x64(’d’), 0x61(’a’), 0x76(’v’), 0x69(’i’), 0x64(’d’)를 put하고 이후에 0x00(null)을 만났으므로 put을 멈춘 것이다.

reference.

[1] ASCII Table, Wikipedia
[2] Extended ASCII, Wikipedia
 
Share article

rudevico