programing

malloc과 calloc의 차이점?

prostudy 2022. 7. 26. 22:10
반응형

malloc과 calloc의 차이점?

다음 작업과의 차이점은 무엇입니까?

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

또는 다음과 같이 입력합니다.

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

언제 malloc에서 calloc을 사용하는 것이 좋습니까, 아니면 그 반대로 사용하는 것이 좋습니까?

calloc()는 제로 버퍼를 , "는 "초기화 버퍼"를 제공합니다.malloc()메모리를 초기화하지 않은 상태로 둡니다.

할당의 의 경우,calloc를 들어 POSIX의 OS를 ).mmap(MAP_ANONYMOUS) Windows ® WindowsVirtualAlloc을 사용법 정상입니다.malloc.OS os gets 、 OS gets gets gets gets 。callocOS os os os 、 os os os os 。

은 ①을 의미합니다.calloc메모리는, 「깨끗하게」해, 느릿느릿하게 할당해, 카피 온 라이트(copy-on-write)를 시스템 전체의 공유 물리 페이지에 매핑 할 수 있습니다(가상 메모리를 탑재한 시스템을 가정했을 경우).

일부 +할 수도 를 calloc + memset (0)로 읽으려면 .0.

전에 를 사용합니다.malloc따라서 OS에서 새로운 페이지를 가져오는 대신 내부 빈 목록에서 더티 메모리를 제공할 수 있습니다(또는 빈 목록에서 메모리 블록을 0으로 하여 작은 할당 대신).


베베 の ationsations calloc callocOS가 없거나 프로세스 간의 정보 유출을 막기 위해 페이지를 0으로 만드는 고급 멀티 사용자 OS가 아닌 경우 메모리가 0이 됩니다.

임베디드 Linux 에서는 malloc 이 활성화 될 수 있습니다.이는 다중 사용자 시스템에서는 안전하지 않기 때문에 일부 임베디드 커널에서만 활성화 됩니다.

있지 않은 는 Linux와 메모리이 낙관적인 에 의해 입니다.malloc프로그램이 실제 메모리에 도달할 때까지 실제 메모리에 의해 백업되지 않습니다.

calloc메모리에는 실제로 접촉하지 않기 때문에(메모리에 제로가 써집니다), OS가 실제의 RAM(또는 스왑)으로 할당을 백업하고 있는 것을 확인할 수 있습니다.이것이 malloc보다 느린 이유이기도 합니다(그것을 0으로 할 필요가 있을 뿐만 아니라 OS는 다른 프로세스를 스왑하여 적절한 메모리 영역을 찾아야 합니다).

malloc의 동작에 대한 자세한 설명은 예를 들어SO 질문을 참조하십시오.

「 」:
malloc()는 요청된메모리의 합니다.
calloc()합니다.

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

★★★★★★★★★★★★★★
malloc()★★★★★★★★★★★★★★★★★★.
calloc()말록)보다

[ ] [ 수 、 [ 。
malloc()의 인수를 사용합니다: 1개의 인수를 합니다.

  1. 바이트 수

    • 할당할 바이트 수

calloc() 두를 사용합니다.

  1. 길이

    • 할당되는 메모리 블록 수
  2. 바이트 수

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

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

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

이 매뉴얼에 의해calloc처럼 보이다malloc이것은 메모리를 제로 초기화 할 뿐입니다.이것은 주된 차이가 아닙니다.라는 생각calloc메모리 할당을 위한 Copy-on-Write 시멘틱스를 추상화하는 것입니다.메모리를 할당하는 경우calloc모두 0으로 초기화된 동일한 물리 페이지에 매핑됩니다.할당된 메모리의 페이지 중 하나가 물리적 페이지에 기록될 때 할당됩니다.예를 들어 빈 해시 부분은 여분의 메모리(페이지)에 의해 백업되지 않기 때문에 프로세스 간에 공유할 수 있는 단일 제로 초기화 페이지를 가리키기 때문에 이것은 종종 거대한 해시 테이블을 만드는 데 사용됩니다.

가상 주소에 대한 쓰기는 모두 페이지에 매핑됩니다.그 페이지가 제로 페이지일 경우 다른 물리 페이지가 할당되고 제로 페이지가 복사되어 제어 플로우가 클라이언트프로세스로 돌아갑니다이는 메모리 매핑 파일, 가상 메모리 등이 작동하는 방식과 동일합니다.페이징을 사용합니다.

이 토픽에 관한 최적화 사례 1개를 소개합니다.http://blogs.fau.de/hager/2007/05/08/benchmarking-fun-with-calloc-and-zero-pages/

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

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

대.

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

전자는 다음과 같은 경우 작은 할당과 그에 따른 버퍼 오버플로가 발생할 수 있습니다.count보다 크다SIZE_MAX/sizeof *bar. 이 경우 이렇게 큰 개체를 만들 수 없기 때문에 후자는 자동으로 실패합니다.

물론 단순히 오버플로우 가능성을 무시한 부적합한 구현을 경계해야 할 수도 있습니다.대상 플랫폼에서 이 문제가 발생할 경우 오버플로우를 수동으로 테스트해야 합니다.

calloc일반적으로malloc+memset0까지

일반적으로 사용하는 것이 약간 낫다.malloc+memset특히 다음과 같은 작업을 수행할 때는 더욱 그렇습니다.

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

그게 더 좋은 이유는sizeof(Item)컴파일러는 컴파일 시 인식되며 대부분의 경우 컴파일러는 메모리를 제로화하는 최선의 명령으로 대체됩니다.한편, 만약memset에서 일어나고 있다calloc할당 파라미터 사이즈는 에 정리되어 있지 않습니다.calloc코드 앤 리얼memset보통 긴 경계까지 바이트 단위 채우기를 수행하는 코드가 포함되어 있습니다.메모리를 채우는 사이클이 아닌sizeof(long)마지막으로 남은 공간을 바이트 단위로 채웁니다.비록 할당자가 똑똑하게 전화를 걸어도aligned_memset일반적인 루프가 됩니다.

주목할 만한 예외 중 하나는 매우 큰 메모리 청크의 malloc/calloc(일부 power_of_2킬로바이트)를 실행하는 경우입니다.이 경우 할당은 커널에서 직접 이루어집니다.일반적으로 OS 커널은 보안상의 이유로 모든 메모리를 제로로 하기 때문에 스마트한 calloc은 추가 제로로 반환할 수 있습니다.다시 말씀드리지만, 작은 것을 할당하는 경우 malloc+memset을 퍼포먼스로 사용하는 것이 좋습니다.

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

  • calloc()메모리 영역을 할당합니다.길이는 파라미터의 곱이 됩니다. calloc메모리를 ZERO로 채우고 포인터를 첫 번째 바이트로 반환합니다.충분한 공간을 찾을 수 없으면NULL포인터

구문:ptr_var = calloc(no_of_blocks, size_of_each_block); 예.ptr_var = calloc(n, s);

  • malloc()는 REQTRUSTED SIZE 메모리블록을 1개 할당하고 포인터를 첫 번째 바이트로 되돌립니다.필요한 메모리 용량을 찾지 못하면 늘 포인터를 반환합니다.

구문:ptr_var = malloc(Size_in_bytes);malloc()function은 할당하는 바이트 수인1개의 인수를 사용합니다.이 인수는 1개입니다.calloc()함수는 두 개의 인수를 사용합니다.하나는 요소의 수이고 다른 하나는 각 요소에 할당하는 바이트 수입니다.또한.calloc()는 할당된 공간을 0으로 초기화합니다.malloc()하지 않다.

malloc()그리고.calloc()는 동적 메모리 할당을 허용하는 C 표준 라이브러리의 함수입니다.즉, 둘 다 실행 시 메모리 할당을 허용합니다.

시제품은 다음과 같습니다.

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

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

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

  • 구문:malloc()1개의 인수(할당되는 크기)를 사용합니다.calloc()는 2개의 인수(할당되는 블록의 수와 각 블록의 크기)를 사용합니다.

양쪽에서 반환되는 값은 성공한 경우 할당된 메모리 블록에 대한 포인터입니다.그렇지 않으면 메모리 할당 실패를 나타내는 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()대신.

차이점 1:

malloc()는 보통 메모리 블록을 할당하고 초기화 메모리세그먼트입니다

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

차이점 2:

만약 당신이 생각한다면malloc()구문을 지정합니다.인수는 1개뿐입니다.다음 예시를 생각해 보겠습니다.

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()는 기본적으로 캐스트되지 않은 경우 void*를 반환합니다.

할당된 메모리 블록의 크기에는 차이가 없습니다. calloc물리적인 0비트 패턴으로 메모리 블록을 채웁니다.실제로는 메모리 블록에 있는 오브젝트가 다음과 같이 할당되어 있다고 가정하는 경우가 많습니다.calloc리터럴로 초기화된 것처럼 초기값이 있다0예를 들어, 정수의 값은 다음과 같아야 합니다.0, 부동소수점 변수 - 값0.0, pointers : 적절한 늘 값 등입니다.

하지만 현학적인 관점에서 보면calloc(또한memset(..., 0, ...)는 타입의 오브젝트를 올바르게 초기화(제로)하는 것만이 보증됩니다.unsigned char그 외의 모든 것이 올바르게 초기화되는 것은 보증되지 않으며, 정의되지 않은 동작을 일으키는 이른바 트랩 표현을 포함할 수 있습니다.즉, 다른 타입의 경우unsigned char전술한 all-zero-bits patterm은 부정한 값인 트랩 표현을 나타낼 수 있습니다.

그 후 Technical Corrigenda to C99 표준 중 하나에서 동작은 모든 정수 유형에 대해 정의되었습니다(이것은 타당합니다).즉, 현재 C 언어에서는 다음과 같이 정수형만 초기화할 수 있습니다.calloc(그리고memset(..., 0, ...))를 사용하여 일반적인 경우 다른 것을 초기화하면 C언어의 관점에서 정의되지 않은 동작이 발생합니다.

실제로,calloc모두 알고 있듯이 기능합니다만, 그 사용의 유무(상기 사항을 고려했을 경우)는, 유저에게 달려 있습니다.난 개인적으로 완전히 피하고 싶어malloc직접 초기화를 수행합니다.

마지막으로 또 하나의 중요한 세부사항은calloc는 요소 크기에 요소 수를 곱하여 내부적으로 최종 블록 크기를 계산하기 위해 필요합니다.그러면서도calloc는 가능한 산술 오버플로를 감시해야 합니다.요청된 블록 크기를 올바르게 계산할 수 없는 경우 할당에 실패합니다(늘 포인터).그 사이에, 당신의malloc버전에서는 오버플로를 감시하지 않습니다.오버플로우가 발생할 경우에 대비하여 "예측할 수 없는" 메모리 양을 할당합니다.

calloc()에서 선언된 함수<stdlib.h>header는 header에 비해 몇 가지 이점을 제공합니다.malloc()기능.

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

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

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_MAX65535였습니다.무어의 법칙을 고려할 때, 이 현상은 특정 메모리 모델에서 2030년경에 발생할 것으로 의심됩니다.SIZE_MAX == 4294967295메모리 풀은 100 GB 단위입니다.

Benchmarking fun with calloc() 및 Georg Hager's Blog제로페이지에 관한 기사

calloc()를 사용하여 메모리를 할당할 때 요청된 메모리 양은 즉시 할당되지 않습니다.대신 메모리 블록에 속하는 모든 페이지는 일부 MMU 매직(아래 링크)에 의해 모든 0이 포함된 단일 페이지에 연결됩니다.이러한 페이지를 읽기만 하면(벤치마크의 원래 버전에서는 어레이 b, c 및 d에 해당), 데이터는 1개의 제로 페이지에서 제공되며, 이는 물론 캐시에 포함됩니다.메모리 바인드 루프 커널은 이 정도.페이지가 (어떤 방법으로) 쓰여져도 장애가 발생하면 "실제" 페이지가 매핑되고 0 페이지가 메모리에 복사됩니다.이것은 Copy-on-Write라고 불리는 것으로, 잘 알려진 최적화 어프로치입니다(C++ 강의에서는 여러 번 가르쳐 왔습니다).그 후, 제로 읽기 트릭은 그 페이지에서 동작하지 않게 되었습니다.그 때문에, 용장성이 있다고 생각되는 초기화 루프를 삽입한 후, 퍼포먼스가 큰폭으로 저하했습니다.

둘다요.malloc그리고.calloc메모리 할당, 단calloc모든 비트를 0으로 초기화합니다.mallocDoesn't.

Calloc은 malloc +와 동등하다고 할 수 있습니다.memset(memset은 지정된 메모리의 비트를 0으로 설정합니다).

따라서 0으로 초기화할 필요가 없다면 malloc을 사용하는 것이 더 빠를 수 있습니다.

언급URL : https://stackoverflow.com/questions/1538420/difference-between-malloc-and-calloc

반응형