malloc과 calloc의 차이점은 무엇입니까?


780

수행의 차이점은 무엇입니까?

ptr = (char **) malloc (MAXELEMS * sizeof(char *));

또는:

ptr = (char **) calloc (MAXELEMS, sizeof(char*));

malloc 대신 calloc을 사용하거나 그 반대로 사용하는 것이 좋은 생각은 언제입니까?



8
C에서는 위와 같이보다 일반적으로 다음과 같이 작성할 수 있습니다.ptr = calloc(MAXELEMS, sizeof(*ptr));
chqrlie

7
calloc과 malloc + memset의 차이점에 대한 흥미로운 게시물 vorpus.org/blog/why-does-calloc-exist
ddddavidee

2
@ ddddavidee 나도 인터넷에서 많은 답변에 불만을 품은 블로그를 발견했습니다. Nathaniel J. Smith는 분석을 위해 100+ SO 포인트를받을 자격이 있습니다.
lifebalance

답변:


851

calloc()초기화 malloc()되지 않은 버퍼를 제공하는 동시에 메모리는 초기화되지 않습니다.

대규모 할당의 경우 calloc주류 OS에서 구현되는 대부분의 구현은 OS에서 0으로 알려진 페이지 (예 : POSIX mmap(MAP_ANONYMOUS)또는 Windows 를 통해)를 가져 오므 VirtualAlloc로 사용자 공간에이를 작성할 필요가 없습니다. 이것은 정상적인 방법으로 mallocOS에서 더 많은 페이지를 얻는 방법입니다 . callocOS 보증을 활용합니다.

이것은 calloc메모리가 여전히 "깨끗하고"느리게 할당 될 수 있으며, 기록 중 복사가 시스템 전체의 공유 물리적 페이지 0에 매핑 될 수 있음을 의미 합니다. (가상 메모리가있는 시스템을 가정합니다.)

일부 컴파일러는 malloc + memset (0)을 calloc으로 최적화 할 수도 있지만 메모리를로 읽으려면 calloc을 명시 적으로 사용해야합니다 0.

쓰기 전에 메모리를 읽지 않으 malloc려면 OS에서 새 페이지를 가져 오는 대신 내부 여유 목록에서 더티 메모리를 제공 할 수 있습니다. (또는 작은 할당을 위해 사용 가능한 목록에서 메모리 블록을 0으로 만드는 대신).


OS가없는 경우 임베디드 구현은 메모리를 제로 메모리 calloc로 남겨 두거나 calloc프로세스 간 정보 유출을 막기 위해 페이지를 0으로 만드는 멋진 다중 사용자 OS가 아닙니다.

임베디드 Linux에서 malloc은 mmap(MAP_UNINITIALIZED|MAP_ANONYMOUS)다중 사용자 시스템에서 안전하지 않기 때문에 일부 임베디드 커널에서만 사용할 수 있습니다.


224
* alloc 변형은 명확한 니모닉 (clear-alloc, memory-alloc, re-alloc)입니다.
Cascabel

43
할당 된 공간에서 사용하는 모든 것을 설정하려면 malloc ()을 사용하십시오. 데이터의 일부를 초기화하지 않은 상태로 두려면 설정하지 않은 부분을 0으로 만드는 것이 좋습니다.
Jonathan Leffler

268
callocOS가 속도를 높이기 위해 몇 가지 트릭을 수행 할 수 있기 때문에 반드시 더 비싸지는 않습니다. FreeBSD는 유휴 CPU 시간이되면 그것을 사용하여 할당 취소 된 메모리 블록을 없애고 블록으로 플래그를 표시하는 간단한 프로세스를 실행하는 데 사용합니다. 그래서 당신이 할 때 calloc, 그것은 먼저 사전에 0으로 된 블록 중 하나를 찾아서 당신에게 줄 것입니다-대부분 그것을 찾을 것입니다.
Pavel Minaev

28
기본적으로 제로 초기화 할당의 결과로 코드가 "안전한"상태가되면 malloc을 사용하든 calloc을 사용하든 코드가 안전하지 않다고 생각합니다. malloc을 사용하는 것은 데이터 초기화가 필요하다는 좋은 지표입니다. 0 바이트가 실제로 의미가있는 경우에만 calloc을 사용합니다. 또한 calloc은 문자가 아닌 유형에 대해 생각하는 것을 반드시 수행하지는 않습니다. 더 이상 트랩 표현을 사용하거나 IEEE 이외의 플로트를 사용하는 사람은 없지만 코드가 실제로 이식 가능하지 않다고 생각하는 것은 변명의 여지가 없습니다.
Steve Jessop

18
@SteveJessop "안전"은 올바른 단어가 아닙니다. "결정 론적"이 더 나은 용어라고 생각합니다. 타이밍 및 데이터 시퀀스에 의존하는 장애보다는 결정적인 코드는 장애를보다 쉽게 ​​분리 할 수 ​​있습니다. Calloc은 명시 적 초기화에 비해 결정론을 얻는 쉬운 방법입니다.
dennis

362

덜 알려진 차이점은 Linux와 같이 낙관적 메모리 할당을 사용하는 운영 체제 malloc에서 프로그램이 실제로 해당 메모리에 닿을 때까지 반환되는 포인터 가 실제 메모리에 의해 지원되지 않는다는 것입니다.

calloc실제로 메모리를 만지므로 (0을 씁니다) 따라서 OS가 실제 RAM (또는 스왑)으로 할당을 백업하고 있는지 확인할 수 있습니다. 이것이 malloc보다 속도가 느린 이유이기도합니다 (0으로 설정해야 할뿐만 아니라 OS는 다른 프로세스를 교체하여 적절한 메모리 영역을 찾아야합니다).

malloc의 동작에 대한 추가 논의는 예를 들어이 SO 질문 을 참조하십시오


49
calloc0을 쓸 필요가 없습니다. 할당 된 블록이 운영 체제에서 제공하는 대부분의 새 0 페이지로 구성되어 있으면 해당 블록은 그대로 유지됩니다. 물론 이것은 calloc일반 라이브러리 함수 대신 운영 체제에 맞게 조정해야합니다 malloc. 또는 구현 calloc자는 각 단어를 0 화하기 전에 0과 비교할 수 있습니다. 시간이 절약되지는 않지만 새 페이지가 더러워지지는 않습니다.
R .. GitHub 중지 지원 얼음

3
@R .. 재미있는 메모. 그러나 실제로 그러한 구현이 야생에 존재합니까?
Isak Savo

10
모든 dlmalloc유사 구현 memsetmmap새 익명 페이지 (또는 이와 동등한) 를 통해 청크를 얻은 경우 생략합니다 . 일반적으로 이러한 종류의 할당은 256k 정도에서 시작하여 더 큰 청크에 사용됩니다. 나는 제 자신을 제외하고 0을 쓰기 전에 0과 비교하는 구현을 모른다.
R .. GitHub 중지 지원 얼음

1
omalloc또한 memset; calloc응용 프로그램에서 아직 사용하지 않은 페이지 (페이지 캐시)를 건드리지 않아도됩니다. 그러나 매우 원시적 인 calloc구현 은 다릅니다.
mirabilos

10
glibc의 calloc은 OS에서 새로운 메모리를 얻고 있는지 확인합니다. 그렇다면 mmap (..., MAP_ANONYMOUS)가 이미 0으로 설정된 메모리를 반환하기 때문에 쓸 필요가 없다는 것을 알고 있습니다.
Peter Cordes

112

종종 간과되는 장점 중 하나 calloc는 (적합한 구현) 정수 오버플로 취약점으로부터 사용자를 보호하는 데 도움이된다는 것입니다. 비교:

size_t count = get_int32(file);
struct foo *bar = malloc(count * sizeof *bar);

vs.

size_t count = get_int32(file);
struct foo *bar = calloc(count, sizeof *bar);

전자 count가보다 크면 작은 할당 및 후속 버퍼 오버플로가 발생할 수 있습니다 SIZE_MAX/sizeof *bar. 이 경우 후자는 큰 개체를 만들 수 없으므로 자동으로 실패합니다.

물론 오버플로 가능성을 무시하는 부적합한 구현에주의를 기울여야 할 수도 있습니다. 이것이 목표로하는 플랫폼에서 문제가된다면 어쨌든 오버플로에 대한 수동 테스트를 수행해야합니다.


17
분명히 산술 오버플로는 2002 년에 OpenSSH 구멍을 일으켰습니다. 메모리 관련 기능을 사용하여이 문제에 대한 OpenBSD의 좋은 기사 : undeadly.org/cgi?action=article&sid=20060330071917
Philip P.

4
@KomradeP .: 흥미 롭습니다. 안타깝게도 연결 한 기사의 시작 부분에 잘못된 정보가 있습니다. 함께 예 char이다 하지 (A) 내로 결과 다시 할당하는 경우에 오버 플로우가 아니라 구현 정의 변환 char개체.
R .. GitHub 중지 지원 얼음

아마도 설명 목적으로 만있을 것입니다. 컴파일러는 어쨌든 그것을 최적화 할 가능성이 있기 때문에. 광산은이 asm으로 컴파일한다 : push 1
Philip P.

1
@tristopia : 요점은 모든 구현에서 코드를 악용 할 수있는 것이 아니라 추가 가정 없이는 정확하지 않으므로 올바른 / 이동 가능한 사용법이 아니라는 것입니다.
R .. GitHub 중지 지원 얼음

3
@tristopia : 사고 방식이 " size_t64 비트이므로 문제 없습니다"인 경우 보안 버그로 이어질 잘못된 사고 방식입니다. size_t는 크기를 나타내는 추상 유형이며 32 비트 숫자의 임의의 곱을 생각할 이유가 없으며 size_t(참고 : sizeof *bar64 비트 C 구현에서는 원칙적으로 2 ^ 32보다 클 수 있습니다!)에 적합 size_t합니다.
R .. GitHub 중지 지원 얼음

37

이 문서는 calloc을 malloc처럼 보이게 만듭니다. 메모리는 0으로 초기화됩니다. 이것은 주요 차이점이 아닙니다! calloc의 아이디어는 메모리 할당을위한 copy-on-write 의미를 생략하는 것입니다. calloc을 사용하여 메모리를 할당하면 모든 물리적 페이지가 0으로 초기화되는 동일한 물리적 페이지에 매핑됩니다. 할당 된 메모리의 임의의 페이지가 물리적 페이지에 기록 될 때 할당됩니다. 예를 들어 비어있는 해시 부분이 추가 메모리 (페이지)에 의해 백업되지 않기 때문에 HUGE 해시 테이블을 만드는 데 종종 사용됩니다. 그것들은 행복하게 초기화 된 단일 페이지를 가리키며 프로세스 간에도 공유 할 수 있습니다.

모든 가상 주소에 쓰기는 페이지에 맵핑되며, 해당 페이지가 0 페이지 인 경우 다른 물리적 페이지가 할당되고 0 페이지가 복사되고 제어 플로우가 클라이언트 프로세스로 리턴됩니다. 메모리 매핑 파일, 가상 메모리 등이 작동하는 방식과 동일하게 작동합니다. 페이징을 사용합니다.

여기 주제에 대한 최적화 이야기가 있습니다 : http://blogs.fau.de/hager/2007/05/08/benchmarking-fun-with-calloc-and-zero-pages/


26

할당 된 메모리 블록의 크기에는 차이가 없습니다. calloc메모리 블록을 물리적 인 0 비트 패턴으로 채 웁니다. 실제로 할당 된 메모리 블록에있는 객체 calloc는 마치 리터럴로 초기화 된 것처럼 초기 값 을 갖는다 고 가정합니다 0. 즉, 정수는 0부동 소수점 변수 -value- 0.0포인터-적절한 null 포인터 값 , 등등.

그러나 pedantic 관점에서 calloc(뿐만 아니라 memset(..., 0, ...)) 유형의 객체를 (0으로) 올바르게 초기화하는 것만 보장됩니다 unsigned char. 다른 모든 것은 제대로 초기화되지 않으며 , 소위 트랩 표현을 포함하여 정의되지 않은 동작을 유발할 수 있습니다. 다시 말해서, unsigned char상기 언급 된 모든 0 비트 이외 의 유형에 대해 patterm은 잘못된 값, 트랩 표현을 나타낼 수 있습니다.

나중에 Technical Corrigenda to C99 표준 중 하나에서 동작은 모든 정수 유형에 대해 정의되었습니다. 즉, 공식적으로 현재 C 언어에서는 calloc(및 memset(..., 0, ...))로 정수 유형 만 초기화 할 수 있습니다 . 일반적인 경우에이를 사용하여 C 언어의 관점에서 정의되지 않은 동작이 발생합니다.

실제로, calloc우리 모두가 알고 있듯이 작동하지만, 위의 사항을 고려할 것인지의 여부는 귀하에게 달려 있습니다. 나는 개인적으로 그것을 완전히 피하고 malloc대신 사용하고 내 자신의 초기화를 수행 하는 것을 선호합니다 .

마지막으로, 또 다른 중요한 세부 사항은 요소 크기에 요소 수를 곱하여 calloc최종 블록 크기를 내부적 으로 계산하는 데 필요 하다는 것 입니다 . 그렇게하는 동안 calloc산술 오버플로가 발생할 수 있는지 확인 해야합니다. 요청 된 블록 크기를 올바르게 계산할 수 없으면 할당 실패 (널 포인터)가 발생합니다. 한편,malloc 버전은 오버플로를 감시하지 않습니다. 오버플로가 발생하는 경우 "예측할 수없는"메모리 양을 할당합니다.


"또 다른 중요한 세부 사항"단락에 따르면 : 오버플 로 memset(p, v, n * sizeof type);가 발생할 수 있기 때문에 문제가 되는 것 같습니다 n * sizeof type. for(i=0;i<n;i++) p[i]=v;강력한 코드를 위해 루프 를 사용해야 할 것 같아요 .
chux-복 직원 모니카

다른 null 포인터 표현을 사용하는 구현이 있기 때문에 구현에서 null 포인터로 all-zeros를 0으로 사용해야한다고 코드가 주장 할 수있는 표준 수단이 있다면 도움이 될 것입니다. 비교적 드문; calloc () 또는 memset을 사용하여 포인터 배열을 초기화 할 수 있으면 그러한 구현에서 실행할 필요가없는 코드가 더 빠를 수 있습니다.
supercat

@chux 아니요, n요소의 크기가있는 요소가 있는 배열 이 있으면 객체의 최대 크기가보다 작아야하므로 오버플 sizeof typen*sizeof type할 수 없습니다 SIZE_MAX.
12431234123412341234123

@ 12431234123412341234123 배열 크기 <= 에 대해서는 참 SIZE_MAX이지만 여기 에는 배열 이 없습니다 . 에서 반환 된 포인터 calloc()가 초과 한 것보다 할당 된 메모리를 가리킬 수 있습니다 SIZE_MAX. 대부분의 구현에 2 개 인수의 제품을 제한 할 calloc()SIZE_MAX, 아직 C 사양은 제한을 부과하지 않습니다.
chux-복원 Monica Monica

21

기사의 은 calloc 재미를 벤치마킹 () 및 제로 페이지게오르그 헤거의 블로그

calloc ()을 사용하여 메모리를 할당 할 때 요청 된 메모리 양이 즉시 할당되지 않습니다. 대신, 메모리 블록에 속하는 모든 페이지는 일부 MMU 매직 (아래 링크)에 의해 모든 0을 포함하는 단일 페이지에 연결됩니다. 이러한 페이지가 읽기 전용 인 경우 (원래 벤치 마크 버전의 배열 b, c 및 d에 해당) 데이터는 단일 제로 페이지에서 제공되며 물론 캐시에 적합합니다. 메모리 바운드 루프 커널의 경우 너무 많습니다. 어떤 방법 으로든 페이지에 쓰면 오류가 발생하고 "실제"페이지가 매핑되고 0 페이지가 메모리에 복사됩니다. 이것을 잘 알려진 최적화 접근 방식 (copy-on-write)이라고합니다 (C ++ 강의에서 여러 번 가르쳤습니다). 그 후


링크는 어디에 있습니까?
Rupesh Yadav.

2
첫 번째 답변은 Georg Hager의 블로그 링크입니다.
Ashish Chavan

11

calloc일반적 malloc+memset으로 0입니다

일반적으로 malloc+memset다음과 같은 작업을 수행 할 때 명시 적 으로 사용하는 것이 약간 좋습니다 .

ptr=malloc(sizeof(Item));
memset(ptr, 0, sizeof(Item));

sizeof(Item)컴파일 타임에 컴파일러에 대해 알고 있기 때문에 컴파일러 가 더 좋으며 대부분의 경우 컴파일러는 메모리를 제로화하는 가장 좋은 명령으로 대체합니다. 반면에에서 memset발생 calloc하는 경우 할당의 매개 변수 크기가 calloc코드 에서 컴파일되지 않고 실제 memset호출되는 경우가 많습니다. 여기에는 일반적으로 채우기주기보다 긴 경계까지 바이트 단위 채우기를 수행하는 코드가 포함됩니다. sizeof(long)청크 단위로 메모리를 채우고 마지막으로 남은 공간을 바이트 단위로 채 웁니다. 할당자가 일부를 호출하기에 충분히 똑똑하더라도aligned_memset 여전히 일반 루프입니다.

주목할만한 예외는 매우 큰 메모리 청크 (일부 power_of_two 킬로바이트)의 malloc / calloc을 수행하는 경우 커널에서 직접 할당을 수행 할 수 있습니다. OS 커널은 일반적으로 보안상의 이유로 모든 메모리를 제로화하므로, 충분한 calloc은 추가 제로화로이를 반환 할 수 있습니다. 다시 말하지만, 당신이 아는 것을 할당하는 것이 작 으면 malloc + memset 성능 측면에서 더 나을 수 있습니다.


시스템 라이브러리에서 기능의 일반적인 구현이 사용자 코드에서 동일한 작업보다 반드시 빠를 필요는 없다는 사실을 상기시켜 +1.
Patrick Schlüter

1
두 번째 포인트도 calloc()느립니다 malloc(): 크기의 곱셈. malloc ()은 종종 컴파일 시간 상수를 갖는 반면 calloc()일반 곱셈 ( size_t64 비트 인 경우에도 매우 비싼 64 비트 * 64 비트 = 64 비트 연산) 을 사용해야합니다 .
Patrick Schlüter

4
glibc calloc은 반환 된 청크를 가장 효율적으로 지우는 방법을 결정하는 데 도움이되는 스마트 한 기능을 가지고 있습니다. 메모리는 메모리입니다. 한 번에 3 바이트를 지우면 메모리를 사용하기 때문에 더 빠르지는 않습니다 struct foo { char a,b,c; };. calloc항상 전체 에드 영역 을 지우려면 항상 malloc+ 보다 낫습니다 . 크기 요소의 int overflow에 대해서도 신중하지만 효율적으로 검사합니다. memsetmalloccalloc
Peter Cordes

8

차이 1 :

malloc() 일반적으로 메모리 블록을 할당하고 초기화 된 메모리 세그먼트입니다.

calloc() 메모리 블록을 할당하고 모든 메모리 블록을 0으로 초기화합니다.

차이 2 :

malloc()구문 을 고려하면 하나의 인수 만 사용합니다. 아래의 다음 예를 고려하십시오.

data_type ptr = (cast_type *)malloc( sizeof(data_type)*no_of_blocks );

예 : int 유형에 10 개의 메모리 블록을 할당하려면

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

calloc()구문 을 고려하면 2 개의 인수가 필요합니다. 아래의 다음 예를 고려하십시오.

data_type ptr = (cast_type *)calloc(no_of_blocks, (sizeof(data_type)));

예 : int 유형에 10 블록의 메모리를 할당하고 모든 것을 ZERO에 초기화하려면

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

유사성:

모두 malloc()calloc()그들이 주조 입력하지 않으면 기본적으로 무효 *를 반환합니다.!


왜 data_type과 cast_type을 다르게 유지합니까?
매진

7

두 가지 차이점이 있습니다.
첫째, 논쟁의 수입니다. malloc()단일 인수 (바이트 단위의 메모리 필요)를 사용하지만 calloc()두 개의 인수가 필요합니다.
둘째, 할당 된 메모리를 초기화 malloc()하지 않고 calloc()할당 된 메모리를 ZERO로 초기화합니다.

  • calloc()메모리 영역을 할당하면 길이는 매개 변수의 곱이됩니다. calloc메모리를 ZERO로 채우고 첫 번째 바이트에 대한 포인터를 반환합니다. 충분한 공간을 찾지 못하면 NULL포인터를 반환합니다 .

구문 : ptr_var=(cast_type *)calloc(no_of_blocks , size_of_each_block);ptr_var=(type *)calloc(n,s);

  • malloc()REQUSTED SIZE의 단일 메모리 블록을 할당하고 첫 번째 바이트에 대한 포인터를 반환합니다. 요청 된 메모리 양을 찾지 못하면 널 포인터를 리턴합니다.

구문 : 그동안 함수는, 바이트 수를 할당하는 하나 개의 인자를 취할 기능 소자의 개수 인, 한 개의 인수를, 다른 바이트의 수는 이러한 요소들의 각각에 할당하도록되어있는 것을 특징으로한다. 또한 할당 된 공간을 0으로 초기화하지만 그렇지는 않습니다.ptr_var=(cast_type *)malloc(Size_in_bytes);malloc()calloc()calloc()malloc()


6

calloc()에 선언 된 함수 <stdlib.h>헤더는을 통해 몇 가지 장점을 제공 malloc()기능.

  1. 주어진 크기의 여러 요소로 메모리를 할당하고
  2. 모든 비트가 0이되도록 할당 된 메모리를 초기화합니다.

6

malloc()calloc() 둘 다 런타임 메모리 할당을 허용 즉, 동적 메모리 할당을 허용 C 표준 라이브러리 함수이다.

프로토 타입은 다음과 같습니다.

void *malloc( size_t n);
void *calloc( size_t n, size_t t)

이 둘 사이에는 주로 두 가지 차이점이 있습니다.

  • 동작 : malloc()메모리 블록을 초기화하지 않고 할당하고이 블록에서 내용을 읽으면 가비지 값이 발생합니다. calloc()반면에, 메모리 블록을 할당하고이를 0으로 초기화하며,이 블록의 내용을 읽으면 분명히 0이됩니다.

  • 구문 : malloc()1 calloc()개의 인수 ( 할당 된 크기)를 취하고 두 개의 인수 (할당 된 블록 수와 각 블록의 크기)를 사용합니다.

성공했을 경우, 양쪽으로부터의 반환 값은 할당 된 메모리 블록에 대한 포인터입니다. 그렇지 않으면 메모리 할당 실패를 나타내는 NULL 이 반환됩니다.

예:

int *arr;

// allocate memory for 10 integers with garbage values
arr = (int *)malloc(10 * sizeof(int)); 

// allocate memory for 10 integers and sets all of them to 0
arr = (int *)calloc(10, sizeof(int));

동일한 기능은 다음과 같이 calloc()하여 얻을 수 malloc()memset():

// allocate memory for 10 integers with garbage values   
arr= (int *)malloc(10 * sizeof(int));
// set all of them to 0
memset(arr, 0, 10 * sizeof(int)); 

더 빠르기 때문에 malloc()사용 하는 것이 바람직 calloc()합니다. 값을 0으로 초기화하려는 경우 calloc()대신 사용하십시오.


5

아직 언급되지 않은 차이점 : 크기 제한

void *malloc(size_t size)까지만 할당 할 수 SIZE_MAX있습니다.

void *calloc(size_t nmemb, size_t size); 에 대해 할당 할 수 있습니다 SIZE_MAX*SIZE_MAX .

이 기능은 선형 주소 지정 기능이있는 많은 플랫폼에서 자주 사용되지 않습니다. 이러한 시스템 calloc()nmemb * size <= SIZE_MAX .

512 바이트 유형을 호출 disk_sector하고 코드에서 많은 섹터 를 사용하려고합니다 . 여기서 코드는 SIZE_MAX/sizeof disk_sector섹터 까지만 사용할 수 있습니다 .

size_t count = SIZE_MAX/sizeof disk_sector;
disk_sector *p = malloc(count * sizeof *p);

더 큰 할당을 허용하는 다음을 고려하십시오.

size_t count = something_in_the_range(SIZE_MAX/sizeof disk_sector + 1, SIZE_MAX)
disk_sector *p = calloc(count, sizeof *p);

이제 그러한 시스템이 그러한 큰 할당을 제공 할 수 있다면 또 다른 문제입니다. 오늘날 대부분은 그렇지 않습니다. 때 그러나 그것은 몇 년 동안 발생한 SIZE_MAX감안할 때 65535이었다 무어의 법칙을 이 특정와 메모리 모델 2030에 대해 발생 될 것입니다 의심 SIZE_MAX == 4294967295기가 바이트의 100와 메모리 풀.


2
일반적으로 size_t는 프로그램이 처리 할 수있는 가장 큰 종류의 객체 크기를 보유 할 수 있습니다. size_t가 32 비트 인 시스템은 4294967295 바이트보다 큰 할당을 처리 할 수 ​​없을 가능성이 크며, 해당 크기의 할당을 처리 할 수있는 시스템은 거의 확실히 size_t32 비트보다 크게 만듭니다 . 유일한 질문은 더 작은 할당에 대한 포인터를 반환하지 않고 calloc제품이 초과하는 값을 사용하여 SIZE_MAX0을 산출 할 수 있는지 여부 입니다.
supercat

일반화에 동의 하지만 C 사양에서는 calloc()할당량을 초과 할 수 있습니다 SIZE_MAX. 16 비트로 과거에 발생했으며 size_t메모리가 계속 저렴 해짐에 따라 일반적 이지 않더라도 앞으로 나아갈 수는 없습니다 .
chux-복원 Monica Monica

1
C 표준은 코드 가 크기를 초과하는 할당 을 요청할 수있게합니다 SIZE_MAX. 그러한 할당이 성공할 수있는 상황이 반드시 필요한 것은 아니다. 그러한 할당을 처리 할 수없는 구현이 반환해야한다는 위임이 특별한 이점이 있는지 확실하지 않습니다 NULL(특히 일부 구현에서 malloc아직 커밋되지 않았고 코드가 실제로 사용하려고 할 때 사용할 수없는 공간에 대한 포인터를 반환 하는 것이 일반적 임) 그것).
supercat

또한 과거에 사용 가능한 주소 범위가 가장 큰 표현 가능한 정수를 초과 한 시스템이 있었을 경우, 수십억 기가 바이트의 저장 용량이 필요하기 때문에 다시 발생할 가능성이 전혀 없습니다. 무어의 법칙이 계속 유지 되더라도 32 비트가 충분하지 않은 지점에서 64 비트가 충분하지 않은 지점으로 이동하면 16 비트가 충분한 지점에서 32가 아닌 지점으로 갈 때보 다 2 배가 더 걸립니다. '티.
supercat

1
왜 4G를 초과하는 단일 할당을 수용 할 수있는 구현하지 정의 할 size_tuint64_t?
supercat

2

블록 수 :
malloc ()은 요청 된 메모리의 단일 블록을 할당하고
calloc ()은 요청 된 메모리의 여러 블록을 할당합니다

초기화 :
malloc ()-할당 된 메모리를 지우고 초기화하지 않습니다.
calloc ()-할당 된 메모리를 0으로 초기화합니다.

속도 :
malloc ()이 빠릅니다.
calloc ()이 malloc ()보다 느립니다.

인수 및 구문 :
malloc ()은 1 개의 인수를 사용합니다.

  1. 바이트

    • 할당 할 바이트 수

calloc ()은 2 개의 인수를받습니다 :

  1. 길이

    • 할당 될 메모리 블록 수
  2. 바이트
    • 각 메모리 블록에 할당 할 바이트 수
void *malloc(size_t bytes);         
void *calloc(size_t length, size_t bytes);      

메모리 할당 방식 :
malloc 함수는 사용 가능한 힙에서 원하는 '크기'의 메모리를 할당합니다.
calloc 함수는 'num * size'와 같은 크기의 메모리를 할당합니다.

이름에 대한 의미 :
malloc이라는 이름은 "메모리 할당"을 의미합니다.
calloc이라는 이름은 "연속 할당"을 의미합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.