일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Win32
- Visual Studio
- 배열
- 지식나눔강좌
- 포인터
- Tips프로그래밍강좌
- 연산자
- 이지스퍼블리싱
- c#
- 함수
- 리뷰
- Programming
- Kotlin
- doit코틀린프로그래밍
- c
- 프로그래밍
- 문법
- CS
- Tips강좌
- 알고리즘
- Desktop
- 김성엽
- tipssoft
- Direct2D
- Windows
- 티스토리
- VS ERROR
- Javascript
- c++
- 백준
- Yesterday
- Today
- Total
F.R.I.D.A.Y.
malloc VS calloc 본문
동적할당은
프로그램에 조금만 규모가 생기면 잘 사용하게 되는 기술로 C언어에서는 함수를 이용해 동적할당을 받는데요, 동적할당을 하는 함수로는 대표적으로 아래와 같은 것들이 있습니다.
malloc | calloc | realloc |
이번 시간에는 위 함수들의 사용 목적에 대해 알아봅니다.
# 이 함수들을 사용하기 위해서는 malloc.h 혹은 stdlib.h 헤더를 추가해야합니다.
malloc
가장 기본이 되는 함수로서, 대체적으로 동적할당을 들어가게 되면 이 함수를 제일 처음 접하지 않을까 합니다. 이 함수는 아래와 같은 기본형을 가지고 있습니다.
void *malloc(size_t size); // from MS DOCS
void* malloc(size_t size);
- size
할당 받을 메모리 크기입니다. 기준은 byte입니다.
from MS DOCS라는 주석이 달린 줄 아래에 똑같이, 그러나 조금 다르게 적었습니다. 반환형이 void가 아닌 void 포인터라는 것을 좀 더 명시적으로 표현한다고 생각해 사용하는 제 나름대로의 코드 작성 규칙입니다.
이 함수는 메모리를 운영체제로부터 이임받는 함수로서, 단순히 파라미터 size에 들어온 크기만큼 반환하는 함수입니다. 만일 실패했다면 NULL이 반환됩니다.
calloc
malloc()에서 한가지 기능이 추가된 함수입니다. 그 한가지 기능은 malloc()함수가 받아오는 메모리의 내용을 0으로 초기화합니다. malloc()함수는 앞서 설명드린 것과 같이 단순히 명령한 메모리 크기만큼 메모리를 받아 반환하므로 할당한 메모리에는 쓰레기 값이 존재합니다. 그래서 초기화를 진행해야하는 과정이 종종 필요한데, 초기화를 진행해야하는 경우 대체적으로 0으로 초기화를 진행합니다.
즉, calloc 함수는 malloc으로 받은 메모리 공간을 0으로 초기화하는 기능을 추가한 함수입니다.
함수의 기본형은 다음과 같습니다.
void* calloc(size_t number, size_t size);
- number
할당받을 메모리의 요소 길이, int arr[50]에서 50을 가리키는 값입니다. 원하는 길이만큼 입력하면 됩니다. - size
int arr[50]에서 int, 즉 요소의 크기를 가리키는 값입니다. sizeof 연산자를 이용하면 편합니다.
realloc
malloc()이나 calloc()으로 할당받은 공간이 종종 부족할 수 있습니다. 이럴 때 realloc 함수를 사용합니다. 즉, realloc 함수는 이미 할당받은 공간을 늘일 때 사용합니다.
기본형은 다음과 같습니다.
void* realloc(void *memblock, size_t size);
- memblock
재할당을 시도할 메모리 블럭을 가리키는 포인터입니다. - size
새로 할당을 받을 길이입니다. 기준은 byte입니다. memblock의 길이보다 작은 값(0 제외)을 넣으면 작업하지 않습니다.
이 함수는 조금 특별한 것이, 만일 size 파라미터에 0을 입력하게 되면 할당받았던 메모리 영역을 해제합니다. 즉, free() 로도 사용이 가능한 것이지요. 이 때, 반환하는 값은 NULL입니다. 재할당에 실패했을 때도 NULL이 반환됩니다.
그래서 뭐?
종종 "malloc()이 더 낫다"거나 "calloc()이 더 낫다"라는 말을 듣습니다. 달리 말하면 무엇을 사용하는 것이 바른 것인가 묻고 있는것 같습니다.
저는 malloc 함수를 사용하는 것이 더 낫다고 생각합니다. 대체적으로 동적할당을 받은 뒤에 이어서 값을 받는 행위를 합니다. scanf()와 같은 함수로 말이죠. 이러한 경우에 calloc 함수를 사용하게 되면 불필요한 행위를 추가로 하게 됩니다. 0으로 초기화하는 작업말이죠. 이러한 행위는 속도와 직결되는 문제를 가지고 있습니다. 꼭 0으로 초기화를 해야하는 메모리 공간이 아니라면 굳이 시간 낭비를 해가면서 calloc 함수를 사용할 필요는 없어보입니다.
외국 개발자 의견을 들어보면, 대체적으로 calloc()이 malloc()보다 느리다는 평을 놓는 것 같습니다.
이 글을 보면 calloc 함수의 속도는 플랫폼, 운영체제의 영향을 받는다고 합니다. 링크의 답변자가 말하는 것을 간단히 하면 운영체제가 주기적으로 쓰레기 값을 0으로 초기화하는 작업을 진행한다면 calloc 함수는 0으로 초기화된 메모리 영역을 반환하고자 설계를 한다는 것입니다.
바로 위에 링크한 글에서는 malloc 함수와 memset 함수를 함께 사용하는 것보다는 calloc 함수를 사용하는 것을 권장하고 있습니다. malloc 함수에서 NULL을 반환했을 때 memset 함수를 이용하면 어떻게 되겠느냐고 되묻는데, 대체적으로 어린 개발자들이 예외처리를 잘 하지 않는다는 것을 생각해서 한 말인듯 싶습니다.
편하게 쓰세요.
어차피 malloc 함수나 calloc 함수와 같이 제공되는 함수를 이용하면서 극한의 속도 향상을 꾀하는 것은 맞지 않습니다. 함수에 의존하는 것이 아닌 구조를 개발자 본인이 이해하고 직접 구현함으로써 소위 말하는 갓적화를 이뤄낼 수 있다고 생각합니다.
공부할 때는 편한 함수를 이용하세요. 대신 각 함수의 장단점과 특성은 꼭 알아보시길 바랍니다.
# index
'DEV > C C++' 카테고리의 다른 글
여러 괄호를 사용하는 VPS 찾기 (0) | 2019.11.13 |
---|---|
함수 포인터를 배워야 하는 이유 : 코드 간결화 (0) | 2019.11.01 |
키워드와 예약어 (0) | 2019.08.08 |
scanf()의 문제점 (0) | 2019.06.25 |
함수 인자로 단항연산자 사용하기 (0) | 2019.06.25 |