Stage/Computer Science
-
[메모리] 파일 읽기Stage/Computer Science 2021. 6. 1. 11:33
학습 목표 파일을 읽고 JPEG 파일인지를 검사하는 프로그램을 작성할 수 있다. 1. 파일 읽기 파일의 내용을 읽어서 파일 형식이 JPEG 이미지인지 검사하는 프로그램을 만들어보자. #include int main(int argc, char *argv[]) { if (argc != 2) { return 1; } FILE *file = fopen(argv[1], "r"); if (file == NULL) { return 1; } unsigned char bytes[3]; fread(bytes, 3, 1, file); if (bytes[0] == 0xff && bytes[1] == 0xd8 && bytes[2] == 0xff) { printf("Maybe\n"); } else { printf("No\n");..
-
[메모리] 파일 쓰기Stage/Computer Science 2021. 6. 1. 11:18
학습 목표 사용자로부터 값을 입력받아 파일에 출력하는 프로그램을 작성할 수 있다. 1. 힙 오버플로우, 스택 오버플로우 힙 영역에서 계속 malloc을 호출하게 되면 화살표 방향(아래방향)으로 메모리를 계속 사용하게 된다. 스택 영역에서는 함수가 많이 호출되면 될수록 사용하는 메모리 범위가 점점 위로 늘어나게 된다. 이렇게 힙과 스택 영역에서 계속해서 늘어나다 보면 메모리 용량은 제한되어있기 때문에 두 메모리 영역이 어디선가 충돌하게 된다. 이 같은 현상을 힙 오버플로우 또는 스택 오버플로우라고 말한다. 2. 사용자에게 입력 받기 스택은 get_int, get_string 같은 함수에서도 사용된다. get_int, get_string 함수를 직접 구현해보자. 2.1 get_int #include int ..
-
[메모리] 메모리 교환, 스택, 힙Stage/Computer Science 2021. 6. 1. 00:09
학습 목표 메모리에 저장된 두 값을 교환하는 코드를 작성할 수 있다. 1. 값 교환하기 a와 b의 값을 입력 받고 두 값을 교환하는 코드를 출력해보자. #include void swap(int a, int b); int main(void) { int x = 1; int y = 2; printf("x is %i, y is %i\n", x, y); swap(x, y); printf("x is %i, y is %i\n", x, y); } void swap(int a, int b) { int tmp = a; a = b; b = tmp; } swap 함수를 통해 두 값이 교환 될 것이란 걸 기대할 수 있다. 출력해보면? 나의 예상과는 다르게 x와 y가 바꿔지지 않고 그대로 출력된다. swap 함수가 제대로 작동되..
-
[메모리] 메모리 할당과 해제Stage/Computer Science 2021. 5. 31. 23:51
학습 목표 메모리를 할당하고 해제할 수 있다. 1. 메모리 해제 malloc 함수를 이용하여 정해진 크기만큼 메모리를 할당한 후에는 free라는 함수를 이용해서 메모리를 해제해줘야 한다. 1.1 메모리를 해제하지 않으면? 메모리를 해제하지 않으면 메모리에 저장한 값은 쓰레기 값으로 남게 된다. 이 쓰레기 값들은 메모리 용량을 차지하게 돼서 메모리 낭비가 발생하게 되는데, 이런 현상을 메모리 누수라고 한다. help50 valgrind ./filename valgrind라는 프로그램을 사용하면 지금 내가 작성한 코드에서 메모리 누수가 발생되고 있는지 확인할 수 있다. 2. 메모리 관련 에러 이 코드를 실행시켜 보자. #include void f(void) { int *x = malloc(10 * sizeo..
-
[메모리] 문자열 복사Stage/Computer Science 2021. 5. 31. 23:36
학습 목표 문자열을 복사할 수 있다. 1. 문자열 복사 문자열을 복사하기 위해서 아래 코드를 실행시켜 보자. #include #include #include int main(void) { string s = get_string("s: "); string t = s; t[0] = toupper(t[0]); printf("s: %s\n", s); printf("t: %s\n", t); } string t = s;로 문자열을 복사해놓고 출력을 했다. 입력값으로 s: emma 라고 줬을 때, 나오는 출력 값은 둘 다 Emma로 나온다. s는 emma, t는 EMMA 로 예상했는데, 예상 과는 다른 결과가 나왔다. s 변수에는 문자열 emma가 아닌 문자열 emma가 있는 메모리 주소가 저장되기 때문이다. t도 ..
-
[메모리] 문자열 비교Stage/Computer Science 2021. 5. 31. 23:17
학습 목표 문자열이 저장되어 있는 방식에 근거해서 문자열을 비교하는 방법에 대해 설명할 수 있다. 1. 예시 #include int main(void) { char *s = "EMMA"; printf("%p\n", s); } 코드를 실행하면? "EMMA" 라는 문자열의 첫번째 값인 "E"의 메모리 주소가 출력이 된다. printf("%p\n", &s[0]); printf("%p\n", &s[1]); printf("%p\n", &s[2]); printf("%p\n", &s[3]); 이 코드를 실행하면 어떻게 나올까? s라는 문자열의 첫번째 값인 "E"의 메모리 주소, 두번째 값인 "M"의 메모리 주소..... 2. 문자열 비교 #include #include int main(void) { string s ..
-
[메모리] 문자열Stage/Computer Science 2021. 5. 31. 23:15
학습 목표 문자열 형태의 새로운 자료형인 string이 어떻게 정의되었는지 설명할 수 있다. 1. string의 비밀 우리는 여태껏 수업을 들으면서 문자열을 저장할 때 CS50 라이브러리에 포함된 string 자료형을 사용했다. string s = “EMMA”; 문자열은 결국엔 문자의 배열이다. s[0], s[1], s[2]... 이렇게 인덱스 하나로 문자 하나를 나타낸다. 사실 변수 s는 이런 문자열을 가리키는 포인터가 된다. 더 자세히 말하자면 문자열 중에서 첫번째 문자, 즉 주소 0x123에 있는 s[0]을 가리킨다. 2. CS50 라이브러리 확인해보기 실제 CS50 라이브러리에 가서 확인해보면 string 자료형은 이렇게 나와있다. typedef char *string 이 부분만 보면 이해가 잘 ..
-
[메모리] 포인터Stage/Computer Science 2021. 5. 31. 22:27
학습 목표 포인터 변수를 정의하고 사용할 수 있다. 1. * & 연산자는 메모리의 주소를 가져오는 것이고, * 연산자는 메모리의 주소에 있는 값을 가져오는 것이라고 배웠다. 그리고 우리는 이 연산자를 이용해서 포인터 역할을 하는 변수를 선언할 수도 있다. 1.1 포인터 역할을 하는 변수 선언 #include int main(void) { int n = 50; int *p = &n; printf("%p\n", p); printf("%i\n", *p); } int n 에 50이라는 값이 저장 돼있고, n의 주소를 가져 와서 *p 변수에 저장하고 있다. 한번도 본 적 없는 게 나왔는데, int *p에서 *는 이 변수는 포인터 입니다를 나타내고, int는 이 포인터가 int 타입의 변수를 가리킨다는 의미이다. ..