만약 메모리 할당에 실패하면 malloc은 NULL을 반환하지만, 이 코드는 이를 확인하지 않고 바로 포인터 역참조 수행 → 심각한 오류 가능성.
이는 “안전하지 않은 코드”이며, 실제 제품이나 안정성 요구 상황에서는 절대 권장되지 않음.
2) 메모리 및 동작 과정
성공 시: 2번과 동일하게 16바이트 할당, 배열 요소 출력, 메모리 해제 정상 수행.
실패 시: pk == NULL → pk[0] 접근 시 NULL 포인터 역참조 → 프로그램 크래시 또는 비정의 동작 발생.
3) 심층적 해석 및 주의
동적 할당 시 NULL 체크를 하지 않는 것은 치명적.
특히 대규모 프로그램이나 메모리 부족 상황에서는 필수 예외 처리.
malloc 호출 직후 반드시 NULL 여부 확인 후 처리하는 것이 올바른 코딩 습관.
4) 요약
NULL 체크 생략 시 프로그램 안정성 저하
반드시 할당 성공 확인 후 포인터 사용 권장
4. int 4개 동적 배열 할당 및 출력
#include<stdio.h>#include<stdlib.h>intmain()
{
int*p=malloc(sizeof(int) *4);
p
[0] = 10; p[1] = 20; p[2] = 30; p[3] = 40;
for (int i = 0; i < 4; ++i)
printf("int: %d\n", p[i]);
free(p);
}
---
### 1) 코드 심화 설명
- `malloc(sizeof(int) * 4)`로 `int` 4개 공간을 동적 할당.
- `p[0]~p[3]`에 순차적으로 10, 20, 30, 40 할당.
- `for`문으로 각 요소 출력.
- `free(p);`로 메모리 해제.
---
### 2) 메모리 및 동작 과정
| 단계 | 설명 | 메모리 및 포인터 상태 |
|-------|-------------------------------------------------|--------------------------------------------|
| 1 | `malloc` 호출하여 4 * 4바이트 = 16바이트 할당 | `p`는 연속된 16바이트 힙 영역 시작 주소 저장 |
| 2 | 각 인덱스에 값 저장 | `p[0]`=10, `p[1]`=20, ... |
| 3 | 출력 | 10, 20, 30, 40 순차 출력 |
| 4 | `free(p)` | 메모리 반환, 포인터는 무효 상태 |
---
### 3) 심층적 해석
- `int` 크기는 보통 4바이트, 컴파일러 및 시스템마다 다를 수 있음.
- 메모리 할당 크기는 반드시 `sizeof(int)`를 사용해 플랫폼 독립적 코드 작성 권장.
- 힙 메모리는 연속 공간이므로 `p[i]` 인덱스 접근 안전.
- `free` 호출은 동적 할당 메모리를 해제하여 메모리 누수 방지.
---
### 4) 요약
- `malloc`으로 배열 크기만큼 메모리 확보 → 값 할당 및 출력 → 해제
- `sizeof` 연산자 사용 권장
---
# 5. int 4개 동적 배열 할당 및 초기화 (0으로)
```c
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* p = malloc(sizeof(int) * 4);
for (int i = 0; i < 4; ++i)
p[i] = 0;
for (int i = 0; i < 4; ++i)
printf("int: %d\n", p[i]);
free(p);
}
PrintArray 함수 매개변수 int arr[]는 실제로 int* arr 포인터와 동일한 의미.
data 배열은 크기 5로 스택에 생성됨.
PrintArray(data, 5) 호출 시 배열 이름 data는 첫 요소의 주소를 함수에 전달.
함수 내 for문에서 arr[i]는 *(arr + i) 형태 포인터 연산으로 값 접근.
마지막 printf("\n")로 줄 바꿈.
2) 메모리 및 동작 과정
단계
설명
메모리 및 포인터 상태
1
data
배열 스택에 5개 int 저장 | data 시작 주소를 PrintArray에 전달 |
| 2 | PrintArray 내 arr는 data 시작 주소 포인터 | arr[i]는 data[i]와 동일 값 참조 |
| 3 | 10 20 30 40 50 순서대로 출력 | 배열 요소 정상 출력 |
| 번호 | 주제 | 핵심 내용 | 메모리 영역 | 주의점 |
| -- | ------------- | ----------------- | ------ | --- |
| 1 | 힙 메모리 할당 및 해제 | `malloc`으로 double | | |
2개 크기 할당 후 사용 및 해제 | 힙 (동적 메모리) | 할당 크기 정확히, `free` 호출 필수 |
| 2 | 초기화 없는 `malloc` | 초기화 안 됨, 쓰레기 값 가능 | 힙 | 초기화 필요 시 직접 수행 또는 `calloc` 권장 |
| 3 | `calloc` 사용 | 0으로 초기화 된 메모리 할당 | 힙 | NULL 체크 필수 |
| 4 | 지역 변수 vs 전역 변수 | 지역 변수는 함수 호출 시 생성, 전역 변수는 프로그램 전체 | 스택 / 데이터 영역 | 전역 변수는 모든 함수 접근 가능 |
| 5 | 지역 변수 주소 반환 문제 | 반환 후 주소 무효화, 정의되지 않은 동작 발생 | 스택 | 지역 변수 주소 반환 금지 |
| 6 | 배열 함수 전달 | 배열 이름은 주소, 함수에서 배열 크기 필요 | 스택 | 배열 크기 별도 전달 |
| 7 | 포인터 연산 vs 배열 인덱스 | 동일 동작, 포인터 산술로 주소 계산 | 메모리 | 타입 크기 고려 |
| 8 | 문자열 리터럴과 포인터 | 읽기 전용 영역, 수정 불가 | 읽기 전용 영역 | 수정 시 크래시 위험 |
| 9 | 문자열 배열 선언 | 리터럴 복사 배열 생성, 수정 가능 | 스택 | 수정 가능 |
| 10 | 동적 할당 문자열 복사 및 수정 | 힙 메모리 할당, 수정 가능 | 힙 | `malloc` 후 NULL 체크 및 `free` 필수 |