EXAMPLE이 포함된 C 라이브러리의 malloc() 함수
⚡ 스마트 요약
C 언어의 malloc() 함수는 런타임에 힙 영역에 메모리 블록을 예약하고 해당 블록의 첫 번째 바이트를 가리키는 void 포인터를 반환합니다. 이를 통해 프로그램은 코드가 실제로 실행될 때까지 크기를 알 수 없는 저장 공간을 요청할 수 있습니다.
C에서 malloc이 뭔가요?
malloc() 함수는 메모리 할당을 나타냅니다. 메모리 블록을 동적으로 할당하는 데 사용되는 함수입니다. 지정된 크기의 메모리 공간을 예약하고 메모리 위치를 가리키는 널 포인터를 반환합니다. 반환된 포인터는 일반적으로 void 유형입니다. 이는 모든 포인터에 malloc 함수를 할당할 수 있음을 의미합니다.
통사론
ptr = (cast_type *) malloc (byte_size);
여기
- ptr은 Cast_type의 포인터입니다.
- malloc 함수는 byte_size의 할당된 메모리에 대한 포인터를 반환합니다.
Example: ptr = (int *) malloc (50)
이 명령문이 성공적으로 실행되면 50바이트의 메모리 공간이 예약됩니다. 예약된 공간의 첫 번째 바이트의 주소는 int 유형의 포인터 ptr에 할당됩니다.
malloc 구현의 또 다른 예를 고려해보세요:
#include <stdlib.h> int main(){ int *ptr; ptr = malloc(15 * sizeof(*ptr)); /* a block of 15 integers */ if (ptr != NULL) { *(ptr + 5) = 480; /* assign 480 to sixth integer */ printf("Value of the 6th integer is %d",*(ptr + 5)); } }
출력:
Value of the 6th integer is 480
*ptr 선언이 나중에 다른 데이터 유형으로 형변환될 때 코드가 더 안정적이도록 sizeof(int) 대신 sizeof(*ptr)을 사용했음을 유의하십시오.
메모리가 충분하지 않으면 할당이 실패할 수 있습니다. 이 경우 NULL 포인터를 반환합니다. 따라서 NULL 포인터를 확인하는 코드를 포함해야 합니다.
할당된 메모리는 연속적이며 배열처럼 취급할 수 있다는 점을 명심하십시오. 우리는 다음을 사용할 수 있습니다. 포인터 대괄호 [ ] 대신 연산 연산자 +를 사용하여 배열 요소에 접근하는 것이 좋습니다. ++ 또는 += 연산자를 사용하면 포인터에 저장된 주소가 변경되므로 배열 요소를 참조할 때는 + 연산자를 사용하는 것이 좋습니다.
Malloc 함수는 문자 데이터 유형뿐만 아니라 구조체와 같은 복합 데이터 유형에서도 사용할 수 있습니다.
C 언어에서 malloc()을 사용하는 이유는 무엇일까요?
정적 배열과 일반 변수는 프로그램 컴파일 시 크기가 고정되어 실제 필요한 데이터 양이 적을 경우 공간 낭비가 발생하고, 많을 경우에는 오류가 발생합니다. malloc() 함수는 런타임에 메모리를 요청함으로써 이러한 문제를 해결합니다. 따라서 프로그램은 수신하는 데이터 양에 정확히 맞춰 버퍼 크기를 조정할 수 있습니다. 이러한 런타임 유연성이 바로 malloc의 핵심입니다. 동적 메모리 할당 C.
malloc()을 사용한 동적 할당은 다음과 같은 몇 가지 일반적인 상황에서 적합한 선택입니다.
- 입력량은 프로그램이 실행될 때까지 알 수 없습니다. 예를 들어 파일을 읽거나 사용자가 제공한 목록을 읽는 경우입니다.
- malloc() 함수는 훨씬 더 큰 힙에서 메모리를 가져오기 때문에 제한된 스택 용량을 초과할 정도로 큰 메모리 블록이 필요합니다.
- 데이터는 해당 데이터를 생성한 함수보다 오래 지속되어야 합니다. 힙 메모리는 명시적으로 해제될 때까지 유지되기 때문입니다.
- 프로그램 실행 중에 구조체와 배열의 크기가 커지거나 작아져야 합니다.
예약된 블록은 포인터로 반환되므로 기본 데이터를 복사하지 않고도 함수 간에 저렴하게 전달할 수 있습니다.
malloc() 함수로 할당된 메모리를 해제하는 방법
malloc() 함수로 할당된 메모리는 힙에 저장되며 자동으로 해제되지 않습니다. 프로그램이 메모리를 계속 할당하고 해제하지 않으면 사용 가능한 메모리를 서서히 모두 소모하게 되는데, 이를 메모리 누수라고 합니다. free() 함수는 사용이 완료된 메모리 블록을 시스템에 반환하여 해당 공간을 재사용할 수 있도록 합니다.
free() 함수는 malloc() 함수가 반환한 포인터를 하나의 인자로 받아 전체 블록을 한 번에 해제합니다.
int *ptr; ptr = malloc(10 * sizeof(int)); if (ptr != NULL) { /* use the allocated memory here */ free(ptr); /* release the block */ ptr = NULL; /* avoid a dangling pointer */ }
동적 메모리를 안전하게 관리하려면 다음 규칙을 따르십시오.
- malloc()이 성공적으로 할당될 때마다 free()를 정확히 한 번 호출해야 합니다. 동일한 블록을 두 번 해제하면 정의되지 않은 동작이 발생합니다.
- 해제 후에는 포인터를 NULL로 설정하여 유효하지 않은 포인터로 재사용되지 않도록 합니다.
- malloc() 함수가 반환하지 않은 포인터는 절대로 free() 함수를 사용하여 해제하지 마십시오. 포인터 연산으로 인해 위치가 변경된 포인터도 마찬가지입니다.
- 포인터가 범위를 벗어나기 전에 모든 할당과 그에 상응하는 해제를 수행해야 합니다.
키ping C 언어에서 수동 메모리 관리의 핵심 원칙은 메모리 할당과 해제의 균형을 유지하는 것이며, 이는 메모리 누수와 해제된 메모리를 재사용하여 발생하는 충돌을 모두 방지합니다.
malloc()과 calloc()의 주요 차이점
malloc() 및 호출() 두 함수 모두 힙 메모리를 할당하지만, 인수와 새 블록을 처리하는 방식에서 차이가 있습니다. malloc()은 전체 바이트 수를 인수로 하나 받고, 블록 내용을 초기화하지 않은 상태로 남겨두기 때문에 프로그램이 쓰기 작업을 수행하기 전까지는 예측할 수 없는 쓰레기 값이 저장됩니다. calloc()은 요소의 개수와 각 요소의 크기를 인수로 두 개 받고, 포인터를 반환하기 전에 모든 바이트를 0으로 초기화합니다.
실질적인 차이점은 크게 세 가지로 요약됩니다.
- 초기화: calloc()은 메모리를 0으로 초기화하는 반면 malloc()은 그렇지 않으므로, 값이 어차피 덮어쓰여질 경우 malloc()이 약간 더 빠릅니다.
- 인수: malloc(n * size)라고 쓰지만, 동일한 배열을 예약하려면 calloc(n, size)를 사용합니다.
- 사용 사례: 초기화된 깨끗한 블록이 중요한 경우에는 calloc()을 선택하고, 속도가 우선이고 초기화를 수동으로 처리하는 경우에는 malloc()을 선택하십시오.
두 함수 모두 stdlib.h에 선언되어 있고, 실패 시 void 포인터 또는 NULL을 반환하며, 동일한 free() 함수를 사용하여 메모리를 반환합니다.


