둘 모두 메모리를 할당해준다는 점에서는 동일합니다.

하지만, 특정 상황에서는 어떤 것을 써야 할지 혼돈이 생기는 경우가 많습니다.
물론 대부분 calloc보다는 malloc을 쓰게 되는데 왜 이런 두 종류의 api가 존재하는 것일까 궁금하게 되었습니다.

또, calloc은 두개의 인자를 받도록 되어 있습니다.
왜 똑같이 메모리를 할당받는 데 calloc은 두개의 인자를 malloc은 한개의 인자를 받는 것일까요?
 

추: 답변글들을 꼭 읽어보세요. 이 글은 잘못된 정보를 포함할 수 있습니다.

malloc()

void *malloc(size_t size);

malloc은 size만큼의 메모리를 할당하고 (초기화 없이) 해당 힙 영역을 반환합니다.

int *ptr = malloc(10 * sizeof (int));


calloc()

void *calloc(size_t nelements, size_t bytes);

calloc는 num * size만큼의 메모리를 할당하고 해당 힙 영역을 0으로 초기화하여 반환합니다.

int *ptr = calloc(10,sizeof (int));


물론 둘의 기능상 동일한 비교를 하려면 calloc vs malloc+memset 이라고 해야 맞을 것입니다.
malloc는 0으로 초기화를 수행하지 않으므로 굳이 calloc처럼 초기화를 원한다면 memset도 호출해야 할 것입니다. 


 1. calloc은 왜 두개의 인자를 받는 것일까?
calloc을 왜 설계했는지는 잘 모르겠지만 짧은 검색 실력을 바탕으로 보면 calloc은 두개의 인자를 받음으로써 overflow 여부를 확인할 수 있게 되었습니다. 모든 calloc의 구현에서 이 사실이 유효한지는 알 수 없지만, malloc에서 많이 사용하는 곱셈은 분명 size_t를 넘어서는 메모리 할당이 발생할 경우 잘못된 메모리를 할당받응ㄹ 수 밖에 없지만, calloc은 NULL을 return할 수 있습니다.
http://stackoverflow.com/questions/4083916/two-arguments-to-calloc

2. calloc 과 malloc+memset(..0..) 중 어떤 것이 빠를까?
이 부분에 대해서는 플랫폼마다 논쟁의 여지가 있을 듯 합니다만 일단 calloc이 더 빠를 가능성이 많아 보입니다. 어떤 플랫폼에서는 이미 운영체제가 0으로 초기화한 메모리 영역을 가지고 있을 수 있기 때문에 calloc시 그 영역을 바로 반환하는 것으로 처리될 수 있다고 합니다. 이런 경우 모든 메모리 영역을 0으로 초기화해야 하는 memset보다 단연 빠를 수 있습니다.
하지만, calloc과 malloc만을 비교한다면 malloc이 빠를 확률이 매우 높습니다. OS는 사용자가 malloc을 통해 메모리를 요청했다고 해서 반드시 실제 메모리를 잡아서 전달하는 것이 아닐 수 있습니다.(이 부분은 OOM과 관련하여 추가 정리가 필요할 듯 합니다.) 반면 calloc은 메모리를 잡고 초기화할 우려가 있습니다.
http://stackoverflow.com/questions/2688466/why-mallocmemset-slower-than-calloc
http://stackoverflow.com/questions/3449031/c-calloc-v-malloc

3. 어떤걸 쓰는게 좋을까?
대부분의 경우에는 malloc을 쓰는 것이 좋다고 합니다.
특히 주의해야 할 부분은 calloc이 하는 0으로 초기화란, 단순히 비트 클리어의 역활일 뿐이라는 점입니다.
float 배열을 calloc으로 할당한다고 해서 0.0이 되는 것이 아니라는 점입니다.
또, 메모리를 할당받는 이유가 무언가 쓰기 위함일텐데 대부분의 경우 다시 값을 덮어씌울 것이라면 초기화할 필요가 없습니다.
http://wiki.answers.com/Q/Is_it_better_to_use_malloc_or_calloc_to_allocate_memory

기타
http://stackoverflow.com/questions/1538420/c-difference-between-malloc-and-calloc

 


'프로그래밍 언어 > C/C++' 카테고리의 다른 글

GCC옵션: finstrument-functions  (0) 2011.05.24
linker 관련 링크  (0) 2011.04.15
calloc vs malloc  (7) 2011.04.06
[C언어] a - b < 0 vs. a < b  (0) 2010.10.25
C로 수행시간 체크하기  (0) 2010.09.30
__builtin_expect 키워드  (0) 2010.09.10
  1. ^^ 2011.08.19 10:19 신고

    잘읽었습니다 :)

  2. 2011.09.18 14:16

    비밀댓글입니다

    • 소혼 2011.09.22 21:23 신고

      답변 감사합니다.

      어디까지나 검색한 글을 발번역한거라 틀린 내용이 있을 수 있습니다.

      적어주신 말중에 calloc이 memset과 같은 역할을 해야 하기 때문이라고 하는 건 이해가 안가는데, 혹시 출처가 있는지 궁금합니다.

      malloc+memset과 calloc의 성능은 한번 측정해보겠습니다.
      일반적인 경우라면 둘의 성능은 비슷하거나, calloc이 빨라야(글에서 언급한것처럼 아주 특별한 경우) 정상일 것 같네요.

      역시나 이런 부분들이 궁금해서 검색한 글들을 정리해본 것입니다.

      덕분에 더 공부가 된 것 같습니다. 감사합니다.

  3. vbdream 2013.01.01 02:44 신고

    "float 배열을 calloc으로 할당한다고 해서 0.0이 되는 것이 아니라는 점입니다."는 잘못된 이야기입니다.

    IEEE 754 부동소수점 표기 방식에, float이든 double이든 모든 비트가 0인 경우는 0으로 정의되어있기 때문입니다.
    부동소수점에서 부호 비트가 가장 최상단에 있는 것, 그리고 모든 비트가 0일 때는 0인 것은 정수와의 호환을 염두해 둔 설계입니다.

    • vbdream 2013.01.01 02:50 신고

      그리고 calloc이 설계된 원래 목적은 calloc이 무엇의 약어인지 알면 해결됩니다. calloc은 Contiguous Memory Allocation의 약어로, '연속 메모리 할당' 정도로 번역될 수 있습니다. 여기에서 말하는 연속 메모리(contiguous memory)는 배열을 의미합니다.

      malloc의 원래 목적은 구조체 따위를 위한 메모리 할당, calloc의 원래 목적은 배열을 위한 메모리 할당입니다.

    • 소혼 2013.01.04 21:25 신고

      답변 감사합니다.

      관련 내용을 좀 더 찾아봐야겠네요.

  4. Ww 2018.05.19 12:33 신고

    좋은 글 감사합니다.
    플랫폼마다 다른것인지는 모르겠지만 애플홈페이지에는 정반대로 적혀있어서 혼란스럽네요.
    https://developer.apple.com/library/content/documentation/Performance/Conceptual/ManagingMemory/Articles/MemoryAlloc.html
    calloc은 변수를 사용하기 시작할때 할당이 된다고 쓰여있네요.
    이건 malloc도 미찬가지일려나요...?
    calloc은 malloc+memset과 다르다는 의도인것 같습니다.
    memset을 최대한 skip하도록 되어있는것같네요.

+ Recent posts