* 해당 글은 학과 수업으로 배운 내용과 코드가 포함되어 있으며 개인적 공부 목적으로 업로드하였습니다.
우리는 앞서 C0 memory model에서 두가지의 memory를 살펴보았다.
-Local memories 와 allocated memories
하지만 실제 컴퓨터에는 하나의 memory만 존재한다.
따라서 local 과 allocated memory는 이 큰 하나의 memory에 두가지 segments일 뿐이다.
Allocated memory가 있는 segment를 우리는 heap이라고 부른다.
local memory가 있는 segment를 우리는 stack이라고 부른다.
-function call에 따라 이 stack은 커지기도, 작아지기도 한다.
stack은 점점 커지고 heap이 점점 커져서 서로 만나게 된다면 stack overflow가 발생한다.
Memory의 top 과 bottom segments는 operating system 에 속하게 되어 c0 program은 사용할 수 없다.
NULL의 주소는 0x0000000000000000이다. 이 주소는 program에 속하지 않은 주소로 NULL로 dereference하게 되면 segmentation fault를 일으키는 이유이다.
TEXT segment에는 컴파일된 코드들이 모여져 있다. (각 함수들의 주소가 있다.)
-따라서 이 segment는 read-only이다.
DATA segment 에는 주소를 가진 모든 string이 포함되어 있다. (변수와 fields type이 string일 경우 여기에 속한다)
-이 segment 역시 read-only이다.
Function Pointers
C1 program 이 사용가능한 주소들에는
- array 주소
-memory cell의 주소
-NULL
-string의 주소
-function의 주소 ->우리는 이를 function pointer라고 부른다.
C1 은 address-of-operator("&")를 제공한다
예를 들어 key_hash function이 0x02A라는 주소에서 시작한다면
&key_hash는 0x02A를 return할것이다.
우리는 이 function이 point하는 것을 몇 arguments에 적용하고자 한다.
우리는 이 function pointer를 variable
F = &key_hash
혹은 data structure에 저장할 수 있다.
p->hash = &key_hash;
key_hash function은 string을 input으로 받고 int를 return한다.
우리는 아래와 같이 작성함으로써 string을 input으로 받고 int를 return하는 모든 type의 함수에게 아래와 같은
이름을 줄 수 있다.
typedef int string_to_int_fn(string s);
보통 function type은 '_fn'으로 이름이 끝난다.
우리가 주의해야할 점은 function type은 function이 아니다.
ex) string_to_int_fn("hello")를 쓸수없다.
하지만 function type 이름은 자유롭게 정할 수 있다.
EX) POW function을 function type으로 바꾸는 과정ㅇ르 살펴보자
1) function prototype를 작성한다
int POW(int x, int y);
2) typedef를 앞에 쓴다
typedef int POW(int x, int y);
3) function 이름을 type name으로 바꾼다
typedef int binop_fn(int x, int y);
4) 필요할 경우 contracts도 추가될 수 있다.
typedef int binop_fn(int x, int y);
/*@requires y>=0; @*/
function pointer를 저장할때는 아래와 같이 나타낼 수 있다.
typedef int string_to_int_fn(string s);
string_to_int_fn* F = &key_hash; #address
이때 F 는 pointer(string을 받고 int를 return하는) 여야만 하는데 그 이유는 &key_hash가 주소를 return 하기 때문이다.
따라서 특정 input에 이 pointer를 부르고 싶다면 dereference해야 한다.
int h = (*F)("hello");
# *F("hello")는 *(F("hello"))로 인식됨에 따라 잘못된 type이다.
function pointer도 pointer이기 때문에 F가 NULL이 아닐때만 safe하다.
function의 주소는 절대 NULL이 될 수 없기 때문에
string_to_int_fn* F = &key_hash;
int h = (*F)("hello");
는 safe하다
하지만
string_to_int_fn* F = NULL;
int h = (*F)("hello");
은 unsafe하다
따라서 function pointer operator도 contract가 필요하다
&f -> //@ensures \result !=NULL
'👩💻Developer > Data Structure and Algorithms' 카테고리의 다른 글
AVL tree란 무엇인가? (0) | 2022.11.14 |
---|---|
Binary Search Trees란 무엇인가? (0) | 2022.11.14 |
Hash Dictionary란 무엇인가? (0) | 2022.11.13 |
Generic Pointers란 무엇인가? (0) | 2022.11.13 |
Amortized Analysis를 통해 Unbounded Arrays를 알아보자 (0) | 2022.11.04 |
댓글