์ด์ ํฌ์คํ ์์ ์คํ ํ๋ ์ ๋ด์์ ์ฌ๋ผ์ง๋ ์ง์ญ ๋ณ์๋ฅผ ๋ณด์กดํ๊ธฐ ์ํ ๋ฐฉ๋ฒ์ผ๋ก ๋์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ค๊ณ ํ์๋ค.
๊ทธ๋ฆฌ๊ณ ๋์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ์คํ๊ณผ ํ์ ์์์ผ ํ๋ค.
๋ฉ๋ชจ๋ฆฌ ๋ชจ๋ธ : Stack vs. Heap
Stack์ ๋ฌด์์ ํฌํจํ๋ ๊ฐ?
์ง์ญ ๋ณ์, ์ธ์, ๋ฆฌํด ์ฃผ์
Heap์ด๋ ๋ฌด์์ธ๊ฐ?
๋ณ์์ ๋น์ทํ์ง๋ง ๋ณ์ ์ด๋ฆ์ด ์๋ ๋ฉ๋ชจ๋ฆฌ ์กฐ๊ฐ
(๋์ ๋ณ์, ๋ฌด๋ช ๋ณ์๋ผ๊ณ ๋ถ๋ฅธ๋ค.)
Heap์ ์๋ ๋์ ๋ณ์๋ ํจ์์ ๋ ๋ฆฝ์ ์ผ๋ก ์กด์ฌํ๋ค. ์ด๋ ์ ์ญ ๋ณ์์ ์ ์ฌํ๋ค.
Heap์ ์๋ ๋์ ๋ณ์๋ ๋์ ์ผ๋ก ์์ฑ๊ณผ ์ ๊ฑฐ๊ฐ ๊ฐ๋ฅํ๋ค. ์ด๋ ์ ์ญ ๋ณ์์ ๋ค๋ฅธ ์ ์ด๋ค.
๋ฐ๋ผ์ ๋์ ์ผ๋ก ์์ฑํ๊ณ ์ ๊ฑฐํ๊ธฐ ํ๊ธฐ์ํ ํจ์๊ฐ ์กด์ฌํ๋ค.
- ์์ฑ ํจ์
- malloc(), new()
- ์ ๊ฑฐ ํจ์
- free()
Stack ์ง์ญ ๋ณ์๋ ๋ณ์ ์ ์ธ์ ์ด๋์ ์์นํ๋์ง์ ๋ฐ๋ผ ์์ฑ๊ณผ ์ ๊ฑฐ์๊ธฐ๊ฐ ์๋ฌต์ ์ผ๋ก ์๋ ๊ฒฐ์ ๋๋ค.
๋ฐ๋ฉด, Heap ๋์ ๋ณ์๋ ๊ฐ๋ฐ์์ ์์๋๋ก ํ๋ก๊ทธ๋จ ์คํ ๋์ค ์์ฑ๊ณผ ์ ๊ฑฐ ์์น๋ฅผ ์ ํ ์ ์๋ค.
Java์ Heap๊ณผ Stack์?
์๋ฐ์์๋ Heap์ ์ค์ํ ์์ญ์ด๋ค.
๋์ ๋ณ์๋ฅผ ๋ค๋ฃฌ๋ค๋ ์ ์์ C์ ์ ์ฌํ์ง๋ง, ๋ค๋ฅธ ์ ๋ ๋ง๋ค.
A a = new A();
์๋ฐ์์๋ new A()๋ฅผ ํตํด ํ ์์ญ์ ๋์ ๋ณ์๋ฅผ ์์ฑํ๋ค.
์ด ๋์ ๋ณ์์ ํ์ ์ ํด๋์ค A์ด๋ฉฐ, ์๊ธฐ ์์ ๋ค์ ๊ตฌ๋ถํ๊ธฐ ์ํ '๋ช ์ฐฐํ'์ธ OID๋ฅผ ๊ฐ์ง๋ค.
์ฌ๊ธฐ์ ์ถ๋ก ํ ์ ์๋ ๊ฒ์ ๋์ ๋ณ์์ ํฌ๊ธฐ๋ ํด๋์ค ๊ฐ์ฒด์ ํฌ๊ธฐ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋ค๋ ๊ฒ.
๋ค๋ง, OID์ ํฌ๊ธฐ๋ ๋์ผํ๋ค.
new A()๋ OID๋ฅผ ๋ฆฌํดํ๋ค.
์ฆ, Stack์ ์์นํ ์ง์ญ ๋ณ์ a๋ OID๋ฅผ ๊ฐ์ง๋ค.
void m1(A arg) {
B x = new B(arg);
int y = 100;
...
}
public static void main(String[] args) {
A a = new A();
this.m1(a);
...
}
์์๋ฅผ ํ ๋ฒ ์ดํด๋ณด์.
a๋ new A()๋ฅผ ํตํด ์์ฑ๋ ๋์ ๋ณ์์ OID # 1๋ฅผ ์ง๋๋ค.
์ด ๊ฐ์ด m1 ๋ฉ์๋๋ฅผ ํตํด์ ์ ๋ฌ๋๊ณ , OID #1์ด new B()์ ์ธ์๋ก ์ฝ์ ๋๋ค.
ํด๋์ค B์ ๋์ ๋ณ์๋ฅผ ์์ฑํ๊ธฐ ์ํด OID #1์ด ์ฐธ์กฐ๋๊ณ OID #2๊ฐ ๋ฐํ๋๋ค.
๊ฒฐ๊ตญ ์ง์ญ ๋ณ์ x๊ฐ OID #2๋ฅผ ๊ฐ์ง๊ฒ ๋๋ ๊ฒ์ด๋ค.
๋์ ๋ณ์์ ์ญ์ ๋ garbage collection์ด ๋๋ค.(์ฐธ๊ณ mark-and-sweep ์๊ณ ๋ฆฌ์ฆ)
์ฌ์ฉํ์ง ์๋ ์ฐ๋ ๊ธฐ ๊ฐ์ ์์์ ์ฒ๋ฆฌ๋๋ค๋ ๋ป์ด๋ค.
๋์ ๋ณ์ malloc
malloc์ <stdlib.h>๋ฅผ includeํด์ผ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
malloc์ ํ์ ์ void *์ด๋ค.
(void *) malloc(size_t size);
size_t๋ ๊ฒฐ๊ตญ
unsigned int์ด๋ค.
void * ํ์ ๋ณ์๋ ์ด๋ค ํ์ ๋ด์ฉ์ ์ฃผ์๋ผ๋ ์ฃผ์๋ผ๋ฉด ๋ชจ๋ ๋ด์ ์ ์๋ ๋ณ์์์ ๋งํ๋ค.
ํ์ง๋ง, int ํ ๋ฐ์ดํฐ ์ฃผ์๋ฅผ ๊ฐ์ ธ์ค๋ ํฌ์ธํฐ์ ํ์ ์ void *๋ผ๊ณ ์๊ฐํด๋ณด๋ผ.
ํฌ์ธํฐ๋ ์ด ์ฃผ์๊ฐ ์ผ๋งํผ์ ๋ฐ์ดํธ๋ฅผ ์ฐจ์งํ๋ ์ง ๋ชจ๋ฅธ๋ค.
๋ค์๋งํด ํ ๋ณํ์ด ์๋ค๋ฉด ์ผ๋ง๋ ์ฝ์ ์ง ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค.
malloc๋ ๋ง์ฐฌ๊ฐ์ง๋ค.
๋ฆฌํด ํ์ ์ด void *์ด๋ฏ๋ก ์ ๋๋ก ์ฌ์ฉํ๊ธฐ ์ํด์๋ ํ ๋ณํ์ด ๋ฌด์กฐ๊ฑด ํ์ํ๋ค.
์ฌ์ฉ์ ์๋์ ๊ฐ์ด ํ๋ค.
int *ptr1 = (int*) malloc(sizeof(int));
int *ptr2 = (int*) malloc(sizeof(int)*7);
*ptr1 = 20;
printf("%d \n", *ptr1);
free(ptr1);
int i;
for (i = 0; i < 7; i++) {
ptr2[i] = i+1;
}
for (i =0; i < 7; i++) {
printf("%d ", ptr2[i];
}
free(ptr2);
์ ์์ ๊ฐ์ ๋ ธ๋ ฅ์ ๋์ด malloc์ ์ฌ์ฉํ๋๊ฐ?
๋ฌผ๋ก 'call of value๋ก ์ธํด ์คํ ํ๋ ์ ๋ด์์ ์ฌ๋ผ์ง๊ณ ๋ง์๋ฒ๋ฆฌ๋ ์ง์ญ๋ณ์๋ฅผ ์ํ์ฌ' ๋ผ๊ณ ๋ ํ ์ ์์ง๋ง,
๋๋ถ๋ถ์ ์์์ ๊ฐ์๊ฐ ๋์ ์ผ๋ก ์ ํด์ง ๋ ์ ์ฉํ๊ฒ ์ฌ์ฉํ๊ธฐ ์ํด์๋ค.
์๋? ํ๋ก๊ทธ๋จ์ ์์ํ๊ธฐ ์ด์ ์ int arr[3]๊ณผ ๊ฐ์ด ์์์ ๊ฐ์๊ฐ ๋ฏธ๋ฆฌ ์ ํด์ ธ ์์ผ๋ฉด, ํ์ฉ๋๋ ๋จ์ด์ง์ง ์๋๊ฐ
๋์ ๋ณ์์ ์ญ์
malloc๋ ๋ณ์๋ฅผ ํ ๋น ํด์ ์์ผ์ฃผ๊ธฐ ์ํด free๋ฅผ ์ฌ์ฉํ๋ค.
ํ ๋น๋ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ํ๋ก๊ทธ๋จ์ด ๋๋ ๋๊น์ง ํ๋ก๊ทธ๋จ์ ๊ท์๋๊ธฐ ๋๋ฌธ์ด๋ค.
๋ ์ด์ ์ธ๋ชจ๊ฐ ์์ด์ง๋ฉด free ์์ผ์ฃผ์ด์ผ ํ๋ค.
๐ค ์ free๋ฅผ ์ํค๋ ๊ฐ?
ํ๋ก๊ทธ๋จ์ด ์ข ๋ฃ๋๋ฉด ์ด์งํผ ์ด๊ธฐํ ๋ ๊บผ ๊ตณ์ด ์ free ์ํค๋์ง ์๋ฌธ์ด ๋ ๋ค.
์ฌ๋ฌ๊ฐ์ง ์ด์ ๊ฐ ์์ง๋ง ๋ํ์ ์ผ๋ก ๋๊ฐ์ง๋ก ๋๋๋ค.
1. ๋ฉ๋ชจ๋ฆฌ ๋ฆฌ์์ค ๊ด๋ฆฌ ๋ฌธ์
malloc์ ์ธ์๋ก ์ ๋ฌํ๋ ๋ฉ๋ชจ๋ฆฌ ํฌ๊ธฐ๊ฐ ๋งค์ฐ ํด ์ ์๊ณ , malloc ํธ์ถ ์๊ฐ ๋ง์ ์ ์๋ค.
2. ์ต์ํ ํ๋ก๊ทธ๋จ์ด ์ํ๋๋ ๋์ ํด๋น ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ค๋ฅธ ๊ณณ์ ํ์ฉํ๊ธฐ ์ด๋ ต๋ค.
cf. memory leak, out of memory error
์์ ํ ํ๋ก๊ทธ๋๋ฐ ํจํด
malloc์ ๋ฌธ์ ๊ฐ ์๊ธฐ๋ ๊ฒฝ์ฐ NULL์ ๋ฆฌํดํ๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก malloc์ ์ด์์ฒด์ ์๊ฒ ๋ฉ๋ชจ๋ฆฌ ์กฐ๊ฐ์ ์์ฒญํ๋ค. ํ์ง๋ง ์ด๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํด heap ๋ฉ๋ชจ๋ฆฌ๊ฐ ํ๋ณด๊ฐ ์๋๋ค๋ฉด?
malloc์ NULL์ ๋ฆฌํดํ๋ค.
ํ๋ก๊ทธ๋จ์ ์คํํ๋ ๋์ค์ ๋ฉ๋ชจ๋ฆฌ ํ๋ณด๊ฐ ์๋์ด ํ๋ก๊ทธ๋จ์ด ์ข ๋ฃ๋๋ ๋ถ์์ฌ๋ฅผ ํผํ๊ธฐ ์ํด ์ฐ๋ฆฌ๋ ์ด๋์ ๋์ ํจํด์ ์ค๋นํด์ผํ๋ค.
๊ทธ ์์๋ ๋ค์ ์ฝ๋์ ๊ฐ๋ค.
int * get_number() {
int * p;
p = (int *)malloc(sizeof(int));
if (p == NULL) {
printf("No more memory available. \n");
exit(1);
}
*p = 20;
return p;
}
malloc ์ด ์ธ์ ๋์ ํ ๋น ํจ์
c์ธ์ด ๊ฐ๋ฐ์๋๋ค์ malloc ์ด์ธ์ ๋ค์ํ ๋ฉ๋ชจ๋ฆฌ ๋์ ์์ฑ ๋ฐฉ๋ฒ์ ๊ณ ์ํด๋์ จ๋ค.
calloc, realloc, xalloc ๋ฑ๋ฑ.. ๋ง์ ๋ฐฉ๋ฒ์ด ์์ผ๋, ๊ณตํต์ ์ผ๋ก free๊ฐ ํ์ํ๋ค.
์ด๋ค ์ฐจ์ด์ ์ด ์๋์ง ๋ง๋ง ๋ณด๊ณ ๊ฐ์.
- calloc
- malloc๊ณผ ๋์ผํ๋ ์ธ์ ์ ๋ฌ ๋ถ๋ถ์ด ๋ค๋ฅด๋ค. ๋ฉ๋ชจ๋ฆฌ๋ฅผ 0์ผ๋ก ์ด๊ธฐํ ํ๋ค.
// ์ฒซ ๋ฒ์งธ ๋งค๊ฐ ๋ณ์๊ฐ ๊ณต๊ฐ ํ ๋น์ ๋ช๊ฐ ํ ์ง ์ ํ๋ ๋ถ๋ถ
int *p = (int *) calloc(24, sizeof(int));
- realloc
- ์ด์ ํฌ์ธํฐ p ์ฃผ์์ ๊ณต๊ฐ์ด ๋๋ํ ๋, ์ฃผ์์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ข๋ ํ๋ณด ํ ํ, p๋ฅผ ๊ทธ๋๋ก ๋ฆฌํดํ๋ค.(= ์ฌํ์ฉ)
- ๊ณต๊ฐ์ด ์์ ๊ฒฝ์ฐ์, ์ด์ ํฌ์ธํฐ p๊ฐ ๊ฐ๋ฆฌํค๋ ๊ณต๊ฐ์ ๋ฐ๋ฉํ๊ณ , ์๋ก์ด ๊ณต๊ฐ์ ํ๋ณด/์นดํผํ์ฌ ๋ฆฌํดํ๋ค.
- ์ฆ, ๊ณต๊ฐ์ ๋ฐ๋ฉํ๊ณ ์๋ก์ด ๊ณต๊ฐ์ ํ ๋น!
- ์ผ๋ฐ์ ์ธ ์ ์ ๋ฐฐ์ด์ ๋ํ๋ด๋ ํฌ์ธํฐ์ ๋ํด์๋ ์ฌ์ฉํ ์ ์๋ค.
int *p = (int*)malloc(3 * sizeof(int));
// ๊ธฐ์กด ๊ณต๊ฐ์ ์กฐ๊ธ ๋ ํ๋ณด!
int *new_p = (int *)realloc(p, 5 * sizeof(int));
๋์ ๋ณ์์ ๋ฌธ์ ์
๋์ ๋ณ์๊ฐ ๋ง๋ฅ ์ข์ ์ ๋ง ์์ง๋ ์๋ค.
์ฌ์ฉํ ๋ ํฌ๊ฒ ๋ ๊ฐ์ง ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
1. Dangling Pointer
์ด๋ฏธ free ๋ ๋ฉ๋ชจ๋ฆฌ์กฐ๊ฐ์ ๋ค๋ฅธ ํฌ์ธํฐ ๋ณ์๋ก ์ ๊ทผํ๋ ค๋ ๊ฒฝ์ฐ ๋ฐ์ํ๋ค.
์๋ ์์๋ฅผ ์ดํด๋ณด์
int *p, *q;
p = (int *) malloc(sizeof(int));
*p = 10;
q = p;
free(p);
p = NULL;
*q = 20;
p์ q๋ ๋ชจ๋ ํฌ์ธํฐ ๋ณ์์ด๋ค. p๋ ๋์ ํ ๋น์ ํตํด์ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ๊ณผ ๊ฐ์ ๋ฐ๋๋ค.
๊ทธ๋ฆฌ๊ณ q๋ p ์ฃผ์๋ฅผ ๊ทธ๋๋ก ๋ฐ๋๋ค.
์ด์ p์ ๊ณต๊ฐ์ ํด์ ํด์ฃผ๊ณ NULL ๊ฐ์ ์ค๋ค. ์ด ์ฌ์ค์ด ์๋ฏธํ๋ ๋ฐ๋ q๋ ์ด์ ์ฃผ์๊ฐ ์๋ค๋ ๊ฒ์ด๋ค.
์ฆ, ์ด๋ฏธ free๊ฐ ๋ ๊ณต๊ฐ์ ๋ํด q๋ ์ ๊ทผ ํ ์ ์๋ค. ์ด๋ฌํ ํฌ์ธํฐ p๋ฅผ dangling pointer๋ผ๊ณ ๋ถ๋ฅธ๋ค.
2. Memory Leak(๋ฉ๋ชจ๋ฆฌ ๋์)
๊ณต๊ฐ์ ๋ฐ๋ฉํ์ง๋ ์์๊ณ , ์๊ธฐ๋ ์ ๊ทผํ ์ ์๋ค.
์ด์ ์ dangling pointer๋ 'free๋ ๊ณต๊ฐ์ ์ ๊ทผ์ ํ ์ ์๋ค' ๋ผ๋ ๋ป์ด์๋ค.
๋ฐ๋ฉด, Mamory Leak์ '๊ณต๊ฐ์ด free๋์ง๋ ์๊ณ , ์ ๊ทผ๋ ์๋๋ค.' ๋ผ๋ ๋ป์ด๋ค. ๋ญ๊ฐ ๋ ์ฌ๊ฐํด๋ณด์ด๊ธด ํ๋ค.
์๋ ์์๋ฅผ ๋ณด์.
int *p = (int *) malloc(sizeof(int));
int *q = (int *)malloc(sizeof(int));
*p = 10; *q = 20;
p = q;
p์ q๋ ๊ฐ๊ฐ ๋์ ํ ๋น์ ๋ฐ์ ํฌ์ธํฐ์ด๊ณ , ์ด ํฌ์ธํฐ๋ฅผ ํตํด ๊ฐ์ ๋ฃ์ด์ฃผ์๋ค.
์ด๋, p = q๋ฅผ ํ๋ค๋ฉด? p๋ q์ ์ฃผ์๋ฅผ ๊ฐ์ง๊ฒ๋๋ค. ๊ทธ๋ ๋ค๋ฉด ๊ธฐ์กด์ p์ ์ฃผ์๋ ์ด๋ป๊ฒ ๋๋๊ฐ.
์ ๊ทผ๋ ๋ถ๊ฐ๋ฅํ๋ฉฐ, free๋ ๋์ง ์์ ์ด์ ์ฉกํ ์ํ๊ฐ ๋๋ ๊ฒ์ด๋ค.
'๐ซ Language > C' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[C/C++] typedef, union, enum ํด์ํ๊ธฐ (0) | 2023.06.19 |
---|---|
[C/C++] ํฌ์ธํฐ ๋ฐฐ์ด ๊ทธ๋ฆฌ๊ณ ๋ฐฐ์ด ํฌ์ธํฐ (0) | 2023.06.18 |
[C/C++] ์๋ ํ ๋น ๋ฌธ์์ด๊ณผ ํฌ์ธํฐ (0) | 2023.06.18 |