42seoul에서 libft 과제의 동료평가를 진행하다보니, 고수분들께 평가받으며 내가 몰랐던 개념의 허점에 대해 많이 알게 되었다.
그에 대하여 정리하여 스스로 개념을 보완해보려 한다.
* malloc : 메모리를 할당
1) 프로토타입
#include <stdlib.h>
void *malloc(size_t size);
2) 인자들
size : 메모리 블록의 크기(바이트 단위)
3) 리턴값
메모리 할당에 성공했을 경우 : 할당한 메모리 블록을 가르키는 포인터를 리턴
(해당 포인터의 타입은 언제나 (void *)형이므로, 사용자가 원하는 타입으로 캐스팅 해줘야 함)
매모리 할당에 실패했을 경우 : 널 포인터를 리턴
주소값을 반환받기 떄문에, 할당된 힙 메모리 영역에 접근하려면 포인터를 사용해야한다.
사용 후 반드시 free() 해줘야한다 (메모리 해제)
주의할 점 : unix 기반이랑 리눅스 기반에서 다르게 작동
주의할 점 : malloc()이 실패할 경우, 해당 시점의 포인터에 아무 메모리도 할당되지 않고 null이 리턴된다.
- 사이즈만큼의 여유 메모리 공간이 남아있는지 먼저 확인하고, 여유 공간이 없을 경우에 아무런 할당 없이 null 을 리턴한다.
(처음에 나도 오해한 부분인데, malloc은 조금씩 메모리를 할당 시도를 거듭하다 갑자기 메모리가 부족하면 null을 리턴하는 것이 아니다! 애초부터 메모리 할당이 가능한지, 요청된 사이즈를 보고 확인부터 한다.)
* calloc() 의 특징
malloc과 마찬가지로 힙 메모리를 할당하는 함수이다.
1) 프로토타입
#include <stdlib.h>
void *calloc(size_t nmemb, size_t size);
2) 인자들
nmemb : 다음 파라미터인 size의 갯수. 즉, 할당할 배열의 개수
size : 메모리 블록의 크기(바이트 단위)
3) 리턴값
메모리 할당에 성공했을 경우 : 할당한 메모리 블록을 가르키는 포인터를 리턴 (nmemb * size byte 만큼의 힙 메모리 할당)
(해당 포인터의 타입은 언제나 (void *)형이므로, 사용자가 원하는 타입으로 캐스팅 해줘야 함)
매모리 할당에 실패했을 경우 : 널 포인터를 리턴
calloc()은 size byte 크기의 데이터 type을 nmemb개 저장할 수 있을 크기의 메모리를 할당
즉, size * nmemb 바이트의 메모리를 할당
calloc()은 heap 메모리를 할당하며, malloc()과는 달리 할당된 메모리를 0x00으로 초기화
주소값을 반환받기 떄문에, 할당된 힙 메모리 영역에 접근하려면 포인터를 사용해야한다.
사용 후 반드시 free() 해줘야한다 (메모리 해제)
참고)
만약, nmemb 또는 size가 0이면, NULL 또는 free() 시에 오류가 나지 않도록 적절한 포인터를 리턴한다.
-> unix의 경우에는 1 만큼의 동적할당이 이루어짐
만약, long long (64bit)를 넘어서는 숫자에 대해서는 null을 리턴한다.
-> 초기화할 메모리 주소에 오버플로우가 일어날 경우, 반환된 포인터의 주소가 0x00으로 NULL이 되는 것을 유의해야 한다.
만약 메모리 할당 후에 굳이 메모리에 대한 초기화가 필요 없다면, malloc()을 사용하고, 그렇지 않다면 calloc()을 사용하는 것이 좋다.
* 내 libft 과제 calloc() 구현의 보완점
1) size * count 가 0 일 때 예외처리
2) size * count 가 오버플로우 됬을 때 포인터가 null 주소를 갖도록 처리
참고 자료 출처 :
'IT > 42Seoul' 카테고리의 다른 글
[GET_NEXT_LINE] 구현 준비 (0) | 2021.06.04 |
---|---|
Libft 과제 시 유의점 (테스터기, protected, Makefile) (0) | 2021.05.31 |
[Libft] C 언어 라이브러리 구현_BONUS_보너스 함수 구현2 (0) | 2021.05.30 |
[Libft] C 언어 라이브러리 구현_BONUS_보너스 함수 구현1 (0) | 2021.05.30 |
Makefile 정리2 (0) | 2021.05.25 |