포인터와 malloc 함수 이해하기

오늘도 여김없이 퇴근 후 프로그래밍 공부할 수 있는 이 시간이 소중하다🩵.
..Finallyy! 자료구조 챕터로 들어왔다. 그 전에, 이전에 배운내용을 잠깐 복습하는 시간을 가져봐야지-- 바로, 포인터와 malloc 함수다:) 이 두 개념은 C 언어에서 매우 중요하며, 특히 메모리를 동적으로 할당하고 관리하는 데 필수적이다. 그래서 오늘은 포인터와 malloc 함수의 개념을 간단히 설명하고, 실수하기 쉬운 부분을 실제 코드 예시를 통해 정리해 보고자한다✨.
포인터와 malloc 함수: 기초 개념
포인터란?
포인터는 "주소를 저장하는 변수"다. 즉, 변수의 값이 아니라 그 값이 저장된 메모리 주소를 저장하는 변수이다. 예를 들어, 정수형 변수를 선언하고 그 변수의 값을 포인터로 접근하려면 아래와 같은 방식으로 한다:
int num = 10;
int *ptr = # // ptr은 num의 메모리 주소를 저장
위 코드에서 &num은 변수 num의 메모리 주소를 반환하며, ptr은 이 주소를 저장하게 된다. 따라서 *ptr을 통해 num의 값을 가져올 수 있다.
malloc 함수란?
malloc 함수는 메모리를 동적으로 할당할 때 사용된다. C 언어는 고정된 크기의 메모리 공간만 할당할 수 있기 때문에, 프로그램 실행 중에 메모리의 크기를 유동적으로 바꿀 수 있는 기능이 필요하다. malloc은 이를 가능하게 해주는 함수로, 메모리의 크기를 지정하고 그 주소를 포인터로 반환한다.
int *ptr = malloc(sizeof(int)); // int 크기만큼 메모리 할당
이렇게 malloc을 사용하면 프로그램 실행 중에 필요한 만큼 메모리를 할당하고, 이 메모리를 포인터를 통해 접근할 수 있게 된다.
실수 예시: 포인터 초기화 안 된 상태로 사용하기
이제 포인터를 선언만 하고, 초기화하지 않으면 어떤 오류가 발생할 수 있는지 살펴보자. 아래는 잘못된 코드 예시다:
int main(void) {
int *x;
int *y;
x = malloc(sizeof(int)); // x에 메모리 할당
*x = 42; // x가 가리키는 곳에 42 저장
*y = 13; // y는 초기화되지 않음
}
이 코드에서 문제가 발생한다. y는 포인터로 선언되었지만, 초기화되지 않았다. 즉, y는 어떤 메모리 주소도 가리키지 않고, 쓰레기 값을 가질 수 있다. 이 상태에서 *y = 13;을 실행하면, y가 가리키는 임의의 메모리 주소에 13을 저장하게 되며, 이는 예기치 않은 메모리 오류를 발생시킬 수 있다.
해결 방법: 포인터 초기화하기
포인터를 사용할 때는 항상 초기화가 필요하다. 위 예시에서 y를 초기화하는 방법은 x가 가리키는 메모리 주소를 y에 할당하는 것이다. 아래와 같이 수정할 수 있다:
int main(void) {
int *x;
int *y;
x = malloc(sizeof(int)); // x에 메모리 할당
*x = 42; // x가 가리키는 곳에 42 저장
y = x; // y는 이제 x가 가리키는 주소를 가리킴
*y = 13; // y가 가리키는 곳(즉, x가 가리키는 곳)에 13 저장
}
이렇게 y = x;로 y가 x와 같은 주소를 가리키게 하면, *y = 13;을 실행했을 때 x가 가리키는 메모리 위치에 13이 저장된다. 이 방법은 두 포인터가 동일한 메모리 위치를 가리키도록 하여, 값이 예상대로 변경될 수 있도록 한다.
실수 예시 2: malloc 후 메모리 할당 실패 처리 안 하기
malloc 함수는 메모리 할당에 실패하면 NULL을 반환한다. 이 반환 값을 확인하지 않으면, 할당된 메모리를 잘못 접근할 수 있다. 아래는 그 예시다:
int *ptr = malloc(sizeof(int)); // 메모리 할당
*ptr = 42; // 만약 malloc 실패 시, ptr은 NULL이므로 오류 발생
이 코드에서는 malloc 함수가 실패해 ptr이 NULL을 받을 경우, *ptr = 42;에서 오류가 발생한다. malloc 호출 후에는 반드시 ptr이 NULL인지 확인해야 한다.
int *ptr = malloc(sizeof(int)); // 메모리 할당
if (ptr == NULL) {
printf("Memory allocation failed!\n");
return 1; // 오류 처리
}
*ptr = 42; // 메모리 할당이 성공했을 때만 값 저장
이렇게 NULL 체크를 해주면, 메모리 할당에 실패했을 때 적절한 오류 처리를 할 수 있다.
실수 예시 3: 메모리 해제 안 하기
동적으로 할당한 메모리는 사용 후 반드시 해제해야 한다. 그렇지 않으면 메모리 누수가 발생할 수 있다. 아래는 메모리 해제를 하지 않은 예시다:
int *ptr = malloc(sizeof(int)); // 메모리 할당
*ptr = 42; // 메모리 사용
// 메모리 해제 누락
이 코드에서 메모리 해제를 하지 않으면, 프로그램이 종료될 때까지 해당 메모리가 반환되지 않는다. 메모리 누수가 발생할 수 있으며, 이는 시스템 성능 저하를 일으킬 수 있다. 메모리 해제는 항상 free() 함수를 사용하여 해주어야 한다:
free(ptr); // 메모리 해제
포인터와 malloc 함수는 C 언어에서 매우 중요한 개념이다. 하지만 이들을 잘못 사용하면 프로그램에서 예기치 않은 오류가 발생할 수 있다. 포인터를 사용할 때는 항상 초기화하고, malloc 함수의 반환 값을 확인하며, 동적으로 할당한 메모리는 꼭 해제해 주어야 한다. 이런 작은 실수들이 프로그램의 안정성과 성능에 큰 영향을 미칠 수 있음을 명심하자🥰.
'IT' 카테고리의 다른 글
연결 리스트란? 배열의 한계를 넘는 자료구조 입문 정리 (0) | 2025.04.13 |
---|---|
동적 배열 크기 변경: malloc과 realloc로 메모리 할당하기 (0) | 2025.04.13 |
C 언어로 JPEG 파일 판별하기 - 파일 시그니처를 읽는 법 (0) | 2025.04.08 |
인스타그램 바이럴 마케팅 하는 방법 (2025) (0) | 2025.04.03 |
C에서 사용자 입력을 받아 파일에 저장하는 방법 - scanf, fopen, fprintf 사용법 (0) | 2025.04.02 |
댓글
이 글 공유하기
다른 글
-
연결 리스트란? 배열의 한계를 넘는 자료구조 입문 정리
연결 리스트란? 배열의 한계를 넘는 자료구조 입문 정리
2025.04.13 -
동적 배열 크기 변경: malloc과 realloc로 메모리 할당하기
동적 배열 크기 변경: malloc과 realloc로 메모리 할당하기
2025.04.13 -
C 언어로 JPEG 파일 판별하기 - 파일 시그니처를 읽는 법
C 언어로 JPEG 파일 판별하기 - 파일 시그니처를 읽는 법
2025.04.08 -
인스타그램 바이럴 마케팅 하는 방법 (2025)
인스타그램 바이럴 마케팅 하는 방법 (2025)
2025.04.03