[C언어] malloc 함수

응용 분야

Windows, Unix 등 모든 운영체제에서 사용 가능한 표준 API 기능


기능

동적 메모리 할당(힙 메모리)을 얻는 데 사용되는 표준 C 언어 함수입니다.


헤더

#include <stdlib.h>

※ 함수 사용 시 stdlib.h 파일을 포함하지 않으면 컴파일 시 오류가 발생합니다.


기능

void* malloc(size_t size);

매개변수

  • size_t 크기
    • malloc 함수를 통해 할당할 메모리 양을 입력합니다.


반환 값

성공하기 위해 유효한 포인터 주소를 반환합니다.


실패시 NULL을 반환합니다.

메모리가 부족하면 malloc 함수가 실패할 수 있습니다.

추가 메모리는 남아 있지만 내부적으로 지속적인 메모리 할당 및 할당 해제가 반복됩니다.

메모리가 조각난용량이 유지되더라도 고장이 거의 발생하지 않습니다.

그러므로 malloc을 사용할 때 NULL 포인터가 반환되는지 확인하십시오.


다양한 지식

C언어는 가비지컬렉션(GC)이 없기 때문에 malloc이 할당한 힙 메모리 관리는 개발자의 몫이다.

이것은 양날의 검이다.

올바르게 사용하면 메모리 관리가 매우 효율적일 수 있습니다.

반면에 잘못 사용하면 매우 비효율적인 메모리 사용할수있다, 메모리 누수다음과 같은 매우 중요한 문제가 발생할 가능성이 있기 때문입니다.

그러므로 malloc으로 할당된 포인터는 free 함수로 해제해야 합니다.

메모리 재사용과 관련된 논리를 사용할 때 할당 해제가 필요하지 않다고 생각할 수 있지만 원칙적으로 힙 메모리는 프로세스가 종료되기 전에 할당 해제되어야 합니다.

그러나 최신 운영 체제는 모두 지능적이며 프로세스가 종료될 때 할당된 모든 힙 메모리를 정리합니다.

(먼 과거에는 프로세스가 종료되어도 정리를 해주지 않는 운영체제가 있었다고 합니다…)


malloc 함수에 의해 할당된 메모리 영역 초기화되지 않은 쓰레기 값으로 가득 차 있습니다.

따라서 메모리는 일반적으로 malloc 함수를 통해 할당된 다음 memset 함수를 사용하여 초기화됩니다.

하지만 malloc + memset보다 빠름 calloc 함수에 의해 초기화된 힙 영역의 할당 속도가 더 빠릅니다.

그러므로 malloc + memset 대신 calloc 함수 사용 권장하다.

그렇다면 언제 malloc을 사용해야 할까요?

전체 초기화가 필요하지 않은 경우에는 malloc 함수가 calloc보다 효율적입니다.

typedef struct {
    int a;
    int b;
} test_str_t;

int main()
{
    test_str_t *heap = NULL;

    heap = (test_str_t*)malloc(sizeof(test_str_t));
    if(heap) {
        heap->a = 1;
        heap->b = 2;
        
        ...
        
        free(heap);
    }

    return 0;
}

위의 샘플 코드에서 malloc 함수에 의해 할당된 범위의 모든 변수는 할당된 값이므로 초기화할 필요가 없습니다.

따라서 이 경우에는 malloc이 calloc보다 효율적입니다.


매뉴얼 페이지에서 malloc 함수에 0을 전달하면 NULL, 또는 고유한 포인터 값을 반환할 수도 있습니다.

그리고 그것은 말한다

NULL이 반환되면 할당이 실패한 것으로 간주됩니다.

즉, 크기가 0인 메모리를 할당할 수 없습니다.

그렇다면 포인터의 주소는 무엇일까요?

엄밀히 말하자면 테스트 결과, malloc(0)은 NULL이 아닌 포인터를 반환합니다.

가 되었다, memcpy로 값을 쓰고 읽어보려고 했지만 정상적으로 동작했습니다.

하지만 실제로 사용하는 것은 권장하지 않습니다.

.

가장 큰 이유 중 하나 malloc(0)이 받는 영역의 정확한 크기를 알 수 없기 때문입니다.

오전. (힙 오버플로 버그로 문제가 발생하면 정말 고통스럽습니다.

)

둘째, 이 영역을 사용할 수 있는지 여부에 대한 정확한 문서가 없습니다.

다만, 할당된 포인터의 경우 free() 함수에 넘겨줄 수 있다는 정의가 있다.

사용하지 마시고 무료로 제공하세요.

하지만 malloc() 함수 매개변수에 0을 넣지 않는 예외 처리처음부터 하는 것이 더 현명할 것 같습니다.


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_NAME_LEN  32
#define MAX_VALUE_LEN 64

typedef struct {
    int idx;
    char name(MAX_NAME_LEN);
    char value(MAX_VALUE_LEN);
} my_str_t;

int main() {
    my_str_t *heap = NULL;
    
    heap = (my_str_t *)malloc(sizeof(my_str_t));
    if(heap !
= NULL) { memset(heap, 0, sizeof(my_str_t)); heap->idx = 1; strncpy(heap->name, "Hacker", MAX_NAME_LEN - 1); strncpy(heap->value, "Park", MAX_VALUE_LEN - 1); printf("idx(%d) name(%s) value(%s)\n", heap->idx, heap->name, heap->value); } free(heap); return 0; }

※ 실행결과

idx(1) name(Hacker) value(Park)