강의에서 사용되는 언어는 C언어이다.
컴퓨터는 8개의 비트가 모인 바이트 단위로 정보를 표현한다.
2개의 16진수는 1byte의 2진수로 변환되기 때문에 정보를 표현하기 매우 유용하다.
0x0 == 0
0x9 == 9
0xa == 10
0xf == 15
0x10 == 16
0xff == 255
1111 1111 == 255
int n = 50 으로 변수 n에 50을 저장하면 메모리상에 정수형의 크기인 4바이트만큼의 공간을 차지한다.
50이란 값이 저장된 변수 n은 메모리의 어디에 저장되어 있을까?
c언어에서는 변수가 저장된 메모리 주소를 읽어올 수 있다.
#include <stido.h>
int main(void)
{
int n = 50;
int *p= &n;
#p가 n의 주소를 가리키는 포인터 변수임을 선언
printf("%p\n",p);
#p에 저장된 주소 출력 (%p는 주소포맷)
printf("%i\n",*p);
#p에 저장된 주소 에있는 값 출력
}
&연산자로 변수의 메모리상 주소를 16진수로 받을 수 있다.
*연산자는 메모리상 주소에 저장된 실제 값을 얻을수있다.
%n은 변수n의 주소를 표시하고
*&n은 변수n의 주소에 있는 값을 불러온다.
int *p = &n;
위 코드에서 *는 변수p가 포인터 변수라고 선언한다.
포인터 변수 p 는 n의 주소를 가리킨다.
int는 이 포인터 p가 int타입의 변수를 가리킨다라는 뜻이다.
메모리상에서 포인터 변수 p는 이렇게 저장될 수 있다.
문자열은 단순히 문자의 배열이다.
문자열를 변수에 저장하면 문자열의 첫번째 문자의 주소를 저장한다.
\0(null 종단문자)으로 문자열의 끝을 구분한다
컴퓨터가 문자열을 읽는 방식은 변수에 저장된 주소로 문자열의 시작 문자를 찾아가 \0전 까지 읽는 것이다.
string s = get_string("s:");
string t = s;
c언어에서 문자열을 복사할때 위 사진처럼 하면 변수 t에는 변수s에 저장된 문자열의 주소가 저장된다. (get_string()은 cs50 라이브러리의 함수이다.)
char *s = get_string("s:");
char *t = malloc(strlen(s)+1);
for (int i = 0, n = strlen(s); i < n + 1; i++)
{
t[i] = s[i];
}
문자열의 내용을 복사하려면 malloc함수로 문자열의 크기(null종단문자까지)를 메모리에 할당한 다음, 문자를 하나씩 복사 한다.
c언어 에서는 malloc 함수로 메모리에 원하는 크기만큼 공간을 할당할 수 있다.
할당된 메모리를 사용한 후에는 쓰레기 값이 되기 때문에
free함수로 메모리를 해제해야 메모리 누수를 막을 수 있다.
machine code 영역에 컴파일된 프로그램이 바이너리로 저장되고,
globals 영역에 프로그램 내의 전역함수, 전역변수가 저장되고,
heap 영역은 메모리 할당 요청(malloc)이 왔을 때 하향식으로 변수에 메모리를 할당해준다. 자료구조: 완전이진트리
stack 영역은 프로그램 내 함수와 관련된 것들이 상향식으로 저장된다.
따라서 메모리를 계속 할당하거나 함수를 계속 호출하면 힙영역과 스택영역이 서로 침범하게 되고 힙 오버플로우 또는 스택 오버플로우가 일어나 프로그램 충돌을 야기한다.
버퍼 오버플로우 : 데이터를 메모리에 저장할때 지정된 메모리 바깥에 저장되는것 -> 다른 공간에 저장된 데이터를 침범하여 충돌이 일어날수있음
(버퍼 : 1)완충기, 2)ram)