boostcource
모두를 위한 컴퓨터 과학 (CS50 2019) : David J. Malan
www.boostcourse.org/cs11
실습환경 : CS50 Sandbox & CS50 IDE
힙 오버플로우 / 스택 오버플로우
앞서 본 메모리 구조를 복습해보자.
- machine code : 프로그램이 실행될 때 그 프로그램이 컴파일된 바이너리가 저장된다.
- globals : 프로그램 안에서 저장된 전역 변수가 저장된다.
- heap (힙) : malloc 로 할당된 메모리의 데이터가 저장된다.
- malloc 에 의해 메모리가 더 할당될수록, 점점 사용하는 메모리의 범위가 아래로 늘어난다.
- stack (스택) : 프로그램 내의 함수와 관련된 것들이 저장된다.
- 함수가 더 많이 호출 될수록, 점점 사용하는 메모리의 범위가 위로 늘어난다.
힙과 스택이 사용하는 메모리가 점점 늘어나다보면
제한된 메모리 용량 하에서는 기존의 값을 침범하는 상황도 발생할 것인데
이를 힙 오버플로우 또는 스택 오버플로우라고 칭한다.
사용자에게 입력 받기
스택은 우리가 이전에 써온 get_int나 get_string 과 같은 함수에서도 사용된다.
이런 함수들을 만일 직접 구현한다면 아래와 같은 코드가 될 것이다.
get_int
#include <stdio.h>
int main(void){
int x;
printf("x: ");
scanf("%i", &x);
printf("x: %i\n", x);
}
// > x: 3
// ? x: 3
get_string
#include <stdio.h>
int main(void){
char s[5];
printf("s: ");
scanf("%s", s);
printf("s: %s\n", s);
}
// > s: hello
// ? s: hello
파일 쓰기
사용자로부터 입력을 받아 파일에 저장하는 프로그램을 작성해보자.
#include <stdio.h>
#include <cs50.h>
#include <string.h>
int main(void){
FILE*file = fopen("phonebook.csv", "a");
char *name = get_string("Name: ");
char *number = get_string("Number: ");
fprintf(file, "%s : %s\n", name, number);
fclose(file);
}
fopen이라는 함수를 이용해 FILE이라는 자료형을 불러오고
fprintf 함수를 이용해 printf처럼 파일에 직접 내용을 출력해준다.
그리고 작업의 종료를 알리는 fclose 함수를 사용해 마무리해준다.
실행 후 phonebook.csv 파일이 신규로 생성되고
그 안에 입력한 이름과 번호가 저장됨을 확인할 수 있다.
파일 읽기
이번에는 파일의 내용을 읽어서
파일의 형식이 JPG 이미지인지를 검사하는 프로그램을 작성해보자.
#include <stdio.h>
int main(int argc, char *argv[]){ // 파일명을 사용자로부터 입력 받음
if(argc != 2){ // 파일명이 입력되지 않으면 종료
return 1;
}
FILE*file = fopen(argv[1], "r"); // 파일 읽기(r)
if(file == NULL){ // 파일이 제대로 열리지 않으면 종료
return 1;
}
unsigned char bytes[3]; // 크기가 3인 문자배열 생성
fread(bytes, 3, 1, file); // 파일에서 첫 3byte를 읽어옴
if(bytes[0] == 0xff && bytes[1] == 0xd8 && bytes[2] == 0xff){
printf("Maybe\n");
} else {
printf("No\n");
}
fclose(file); // 파일 닫기
}
이전에 JPG 이미지에 대해서 가볍게 언급한 내용이 있는데
JPG 형식의 파일은 꼭 255 216 255 (16진수로 표현 시 0xFF 0xD8 0xFF)로 시작되어야 한다.
이는 JPG를 정의할 때 만든 약속으로 JPG 파일을 검사하는데 활용할 수 있다.
완성된 프로그램이 의도대로
jpg 파일을 읽고나서는 Maybe라고 출력을, 그 외의 파일을 읽으면 No라고 출력됨을 확인할 수 있다.
+) JPG 외 다른 파일 형식도 이런 약속이 존재하며, 이를 파일 매직 넘버 또는 파일 시그니처라 부른다.
https://www.garykessler.net/library/file_sigs.html 등을 통해 참고할 수 있다.
'CS > CS50' 카테고리의 다른 글
[CS][CS50] 자료구조 - 연결 리스트 / 트리 / 해시 테이블 (0) | 2023.06.19 |
---|---|
[CS][CS50] 자료구조 - malloc과 포인터 복습 / 배열의 크기 조정하기 (0) | 2023.06.19 |
[CS][CS50] 메모리 - 문자열 / 문자열 비교 / 문자열 복사 / 메모리 할당과 해제 / 메모리 교환, 스택, 힙 (0) | 2023.06.19 |
[CS][CS50] 메모리 - 메모리 주소 / 포인터 (1) | 2023.06.18 |
[CS][CS50] 알고리즘 - 재귀 / 병합 정렬 / 정렬 알고리즘의 실행시간 (0) | 2023.06.18 |