
def hello():
arr = [0] * 100 # ์๋์ผ๋ก ๋ฉ๋ชจ๋ฆฌ ํ ๋น๋จ
print("Hello from Python!")
hello()
# ํจ์ ์ข
๋ฃ ์, arr์ ์ฐธ์กฐ ์นด์ดํธ๊ฐ 0์ด ๋๋ฉด GC๊ฐ ์๋ ํด์
#include <stdio.h>
#include <stdlib.h>
void hello() {
int *arr = malloc(sizeof(int) * 4); // ์ฒ์๋ถํฐ ํฌ๊ธฐ๋ฅผ ๋ช
์
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
arr[3] = 40;
printf("%d %d %d %d\n", arr[0], arr[1], arr[2], arr[3]);
free(arr); // ๋ฐ๋์ ์๋ ํด์
}
int main() {
hello();
return 0;
}
Python ์ ์๋ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ ์ธ์ด๋ก, ์ฌ์ฉ์๊ฐ ์ง์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋นํ๊ฑฐ๋ ํด์ ํ ํ์๊ฐ ์๋ค.
๊ฐ์ฒด๊ฐ ๋ ์ด์ ์ฐธ์กฐ๋์ง ์์ผ๋ฉด ๋ด๋ถ์ ์ผ๋ก Garbage Collector(GC) ๊ฐ ์ด๋ฅผ ๊ฐ์งํ์ฌ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํด์ ํ๋ค.
์ด GC๋ ์ฃผ๋ก ์ฐธ์กฐ ์นด์ดํ
(reference counting) ๊ณผ ์ํ ์ฐธ์กฐ ๊ฐ์ง ์๊ณ ๋ฆฌ์ฆ์ ํตํด ์๋ํ๋ค.
C ์์๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ฐ๋ฐ์๊ฐ ์ง์ ํ ๋น(malloc)ํ๊ณ ํด์ (free)ํด์ผ ํ๋ค. ์ด ๊ณผ์ ์ด ์ ๋๋ก ์ด๋ฃจ์ด์ง์ง ์๋๋ค๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์(memory leak), ์ด์ค ํด์ (double free), ํด์ ํ ์ ๊ทผ(use after free) ๊ฐ์ ์น๋ช
์ ์ธ ๋ฒ๊ทธ๊ฐ ๋ฐ์ํ ์ ์๋ค.
์ถ์ฒ : https://gabrieletolomei.wordpress.com/miscellanea/operating-systems/in-memory-layout/
Python ์์ ๋ชจ๋ ๋ฐ์ดํฐ๋ ๊ฐ์ฒด๋ก ๋ค๋ค์ง๋ฉฐ, ์ด ๊ฐ์ฒด๋ค์ ๋ฌด์กฐ๊ฑด ํ(Heap) ์ ์ ์ฅ๋๋ค.
ํจ์ ๋ด๋ถ ๋ณ์์ฒ๋ผ ๋ณด์ด๋ ๊ฒ๋ ์ค์ ๋ก๋ ํ์ ์ ์ฅ๋ ๊ฐ์ฒด์ ๋ํ ์ฐธ์กฐ(reference) ๋ฅผ ๋ค๋ฃจ๋ ๊ฒ์ด๋ค.
C ์์๋ ํจ์ ๋ด์์ ์ ์ธํ ์ผ๋ฐ ๋ณ์๋ ์คํ(stack) ์ ์ ์ฅ๋๊ณ , ๋์ ํ ๋น๋ ๋ฐ์ดํฐ๋ ํ(heap) ์ ์ ์ฅ๋๋ค.
C๋ ์ด์ฒ๋ผ ์คํ๊ณผ ํ์ ๋ช
ํํ ๊ตฌ๋ถํด์ ์ฌ์ฉํ๋ ๋ฐ๋ฉด, Python์ ๋๋ถ๋ถ์ ๋ฐ์ดํฐ๋ฅผ ํ์ ์ฌ๋ฆฐ๋ค๊ณ ๋ณด๋ฉด ๋๋ค.
Python ์์๋ ๋ฆฌ์คํธ, ๋์ ๋๋ฆฌ, ๊ฐ์ฒด ๋ฑ ๋ชจ๋ ๊ฒ์ด "์๋์ผ๋ก" ๋์ ํ ๋น๋๋ฉฐ ์ฌ์ฉ์๊ฐ ์ง์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํด์ ํ์ง ์์๋ ๋๋ ๋์ ๋ฉ๋ชจ๋ฆฌ ํ์๊ฐ ์ธ์ ์ผ์ด๋ ์ง ๋ช ํํ๊ฒ ์์ธกํ๊ธฐ๋ ์ด๋ ต๋ค.
C ์์๋ ๋ช
์์ ์ผ๋ก malloc() ๋ฑ์ผ๋ก ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋นํ๊ณ , ๋ฐ๋์ free()๋ก ๋ฐ๋ฉํด์ผ ํ๋ค. ์ด๋ฅผ ์ํํ ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํ๋ฉฐ, ๊ธด ์๊ฐ ์คํ๋๋ ํ๋ก๊ทธ๋จ์ด๋ ์๋ฒ์์๋ ์น๋ช
์ ์ด๋ค.
๐ฅ ํท๊ฐ๋ฆฌ๋ฉด ์๋๋ ๊ฒ !
๋ ์ธ์ด ๋ชจ๋ ํ ์์ญ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ก๋ ๋์ ํ ๋น์ ์ฌ์ฉํ๊ณ ์์ผ๋
- C์ธ์ด โ ํฌ๊ธฐ ์ง์ ํ์, ๊ฐ๋ฐ์๊ฐ ์ง์ ๊ด๋ฆฌ (malloc, free)
- Python โ ํฌ๊ธฐ ์ง์ ๋ถํ์, ์ธํฐํ๋ฆฌํฐ๊ฐ ์๋ ๊ด๋ฆฌ (GC ํฌํจ)
Python ์์๋ ํฌ์ธํฐ๋ผ๋ ๊ฐ๋
์ด ์ฌ์ฉ์ ์ฝ๋์ ๋๋ฌ๋์ง ์๋๋ค.
๋ชจ๋ ๋ณ์๋ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๋ "ํฌ์ธํฐ ๊ฐ์ ๊ฒ"์ด์ง๋ง, ๊ฐ๋ฐ์๋ ์ด๋ฅผ ์ง์ ์กฐ์ํ ์ ์๋ค.
C ์ธ์ด๋ ํฌ์ธํฐ ๊ธฐ๋ฐ ์ธ์ด๋ค. ๋ฐฐ์ด, ํจ์ ์ ๋ฌ, ๋ฉ๋ชจ๋ฆฌ ์กฐ์ ๋ฑ ๋ค์ํ ์ํฉ์์
์ง์ ์ฃผ์๋ฅผ ๋ค๋ฃจ๋ ํฌ์ธํฐ๋ฅผ ํ์์ ์ผ๋ก ์ฌ์ฉํ๋ค. ์ด๋ก ์ธํด ๊ฐ๋ ฅํ์ง๋ง, ์ค์์ ๋งค์ฐ ์ทจ์ฝํ๋ค.
Python ์ ๊ฐ๋ฐ ์์ฐ์ฑ๊ณผ ์์ ์ฑ์ ์ค์ํ์ฌ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ๋ฅผ ์๋ํํ์ง๋ง,
๊ทธ๋งํผ ๋ฐํ์์์ ์ถ๊ฐ์ ์ธ ์ค๋ฒํค๋๊ฐ ๋ฐ์ํ๋ค.
C ์์๋ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ๋ฅผ ์๋์ผ๋ก ํด์ผ ํ์ง๋ง, ๊ทธ๋งํผ ์ ๋ฐํ ์ต์ ํ๊ฐ ๊ฐ๋ฅํ์ฌ ์ฑ๋ฅ ์ค์ฌ์ ๊ฐ๋ฐ์ ์ ๋ฆฌํ๋ค.
Python ์ C์ฒ๋ผ ์ง์ ๊ธฐ๊ณ์ด๋ก ๋ฒ์ญํ๋ ๊ฒ์ด ์๋๋ผ ์ธํฐํ๋ฆฌํฐ๊ฐ
์ค๊ฐ ์ธ์ด์ธ ๋ฐ์ดํธ์ฝ๋๋ฅผ ํ์ค ํ์ค ํด์ํ๋ฉฐ ์คํํ๊ธฐ ๋๋ฌธ์ ์๋๊ฐ ๋๋ฆฌ๋ค.
C ๋ ์ปดํ์ผ๋ฌ ์ ์ฒด ์์ค์ฝ๋๋ฅผ ๊ธฐ๊ณ์ด๋ก ํ๋ฒ์ ์ปดํ์ผํด์ ์คํํ์ผ์ ์์ฑํ๊ธฐ ๋๋ฌธ์ ์๋๊ฐ ๋น ๋ฅด๋ค.
ํ๋ก๊ทธ๋จ ์คํ ์ค์ ํ์ํ ๋งํผ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ(Heap) ์์ญ์ ํ ๋นํ๋ ๊ฒ์ผ๋ก ์ฌ์ฉ์๊ฐ ์ํ๋ ๋งํผ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋น๋ฐ๊ณ ์ค๊ฐ์ ๋ ํ์ํ๋ค๋ฉด ์ถ๊ฐ๋ก ํ ๋น์ ํ์ํ์ง ์๋ค๋ฉด ํด์ ํ๋ ๋ฐฉ์์ ๋งํ๋ค.
static ํค์๋ ๋ณ์ ๋ฑ์ด ํด๋น.#include <stdio.h>
// ์ ์ญ ๋ณ์ (ํ๋ก๊ทธ๋จ ์ ์ฒด์์ ์ฌ์ฉ ๊ฐ๋ฅ)
int global_array[5];
int main() {
static int static_array[5]; // ํจ์ ๋ด static ๋ณ์
for (int i = 0; i < 5; i++) {
global_array[i] = i + 1;
static_array[i] = (i + 1) * 10;
}
for (int i = 0; i < 5; i++) {
printf("global[%d] = %d, static[%d] = %d\n", i, global_array[i], i, static_array[i]);
}
return 0;
}
#include <stdio.h>
void func() {
int local_array[5]; // ์คํ์ ์ ์ฅ
for (int i = 0; i < 5; i++) {
local_array[i] = i + 1;
}
for (int i = 0; i < 5; i++) {
printf("%d ", local_array[i]);
}
printf("\n");
}
int main() {
func();
// ์ฌ๊ธฐ์๋ local_array์ ์ ๊ทผ ๋ถ๊ฐ (์ด๋ฏธ ํด์ ๋จ)
return 0;
}
| ๋ณ์ ์ข ๋ฅ | ์์ | ์ ์ฅ ์์น | ์์ฑ ์์ | ์๋ฉธ ์์ | ํน์ง |
|---|---|---|---|---|---|
| ์๋ ๋ณ์ (Automatic) | int x = 0; (ํจ์ ๋ด๋ถ) | ์คํ(Stack) | ํจ์ ํธ์ถ ์ | ํจ์ ์ข ๋ฃ | ๊ธฐ๋ณธ ์ง์ญ ๋ณ์, ๋ฉ๋ชจ๋ฆฌ ์๋ ํด์ |
| ์ ์ ๋ณ์ (Static) | static int y = 0; (ํจ์ ๋ด๋ถ) | ๋ฐ์ดํฐ ์์ญ(Data Segment) | ํ๋ก๊ทธ๋จ ์์ | ํ๋ก๊ทธ๋จ ์ข ๋ฃ | ํจ์ ํธ์ถ์ด ๋๋๋ ๊ฐ ์ ์ง |
| ์ ์ญ ๋ณ์ (Global) | int g = 0; (ํจ์ ์ธ๋ถ) | ๋ฐ์ดํฐ ์์ญ(Data Segment) | ํ๋ก๊ทธ๋จ ์์ | ํ๋ก๊ทธ๋จ ์ข ๋ฃ | ๋ชจ๋ ํจ์์์ ์ ๊ทผ ๊ฐ๋ฅ |
| ๋์ ๋ณ์ (Dynamic) | malloc(sizeof(int) * 10); | ํ(Heap) | malloc ํธ์ถ ์ | free ํธ์ถ ์ | ํฌ๊ธฐ ์คํ ์ค ๊ฒฐ์ , ์๋ ํด์ ํ์ |
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr = malloc(sizeof(int) * 5); // int 5๊ฐ ๊ณต๊ฐ ํ ๋น
if (arr == NULL) {
printf("๋ฉ๋ชจ๋ฆฌ ํ ๋น ์คํจ\n");
return 1;
}
for (int i = 0; i < 5; i++) {
arr[i] = i + 1;
}
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]);
}
free(arr); // ํด์
return 0;
}
memset ๋ฑ์ผ๋ก ์ง์ ์ด๊ธฐํํด์ผ ํ๋ค. int arr[5];
memset(arr, 0, sizeof(arr)); // ๋ชจ๋ ๋ฐ์ดํธ๋ฅผ 0์ผ๋ก ์ฑ์
calloc๋ณด๋ค ์ผ๋ฐ์ ์ผ๋ก ๋น ๋ฅด๋ค.sizeof(ํ์
) * ๊ฐ์ ํํ๋ก ๋ฐ์ดํธ ํฌ๊ธฐ๋ฅผ ์ง์ ๊ณ์ฐํด์ผ ํ๋ค.NULL ๋ฐํ ๊ฐ๋ฅ์ฑ ์ฒดํฌ ํ์.#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr = calloc(5, sizeof(int)); // int 5๊ฐ ๊ณต๊ฐ ํ ๋น + 0์ผ๋ก ์ด๊ธฐํ
if (arr == NULL) {
printf("๋ฉ๋ชจ๋ฆฌ ํ ๋น ์คํจ\n");
return 1;
}
printf("calloc์ผ๋ก ํ ๋น๋ ๋ฐฐ์ด (0์ผ๋ก ์ด๊ธฐํ๋จ):\n");
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]); // ์ ๋ถ 0 ์ถ๋ ฅ
}
printf("\n");
free(arr);
return 0;
}
calloc(๊ฐ์, ํฌ๊ธฐ) ํํ๋ก ์ฌ์ฉ. ๋ด๋ถ์ ์ผ๋ก ๋ ๊ฐ์ ๊ณฑํด ์ ์ฒด ํฌ๊ธฐ๋ฅผ ๊ณ์ฐํ๋ค.malloc๋ณด๋ค ์ฝ๊ฐ ๋๋ฆด ์ ์๋ค(๋๋ถ๋ถ ๋ฏธ๋ฏธํ ์ฐจ์ด).#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr = malloc(sizeof(int) * 3); // ์ฒ์ 3์นธ ํ ๋น
if (arr == NULL) {
printf("๋ฉ๋ชจ๋ฆฌ ํ ๋น ์คํจ\n");
return 1;
}
for (int i = 0; i < 3; i++) {
arr[i] = (i + 1) * 10;
}
printf("realloc ์ :\n");
for (int i = 0; i < 3; i++) {
printf("%d ", arr[i]);
}
printf("\n");
// ํฌ๊ธฐ๋ฅผ 5์นธ์ผ๋ก ํ์ฅ
arr = realloc(arr, sizeof(int) * 5);
if (arr == NULL) {
printf("๋ฉ๋ชจ๋ฆฌ ์ฌํ ๋น ์คํจ\n");
return 1;
}
printf("realloc ํ (๋์ด๋ ๋ถ๋ถ ์ด๊ธฐํ ์ ๋จ, ์ฐ๋ ๊ธฐ ๊ฐ ๊ฐ๋ฅ):\n");
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]);
}
printf("\n");
free(arr);
return 0;
}
int *arr = malloc(sizeof(int) * 5);
// ํฌ๊ธฐ ๋๋ฆฌ๊ธฐ
arr = realloc(arr, sizeof(int) * 10); // โ ๏ธ ์ํ
if (arr == NULL) {
// ์ฌ๊ธฐ ์ค๋ฉด arr์ NULL์ด ๋ค์ด๊ฐ โ ๊ธฐ์กด ๋ฉ๋ชจ๋ฆฌ ์ฃผ์ ์์ด๋ฒ๋ฆผ โ ๋ฉ๋ชจ๋ฆฌ ๋์ ๋ฐ์
}
| ์ฃผ์ ํจ์๋ช | ๊ธฐ๋ฅ | ํน์ง |
|---|---|---|
malloc(size) | size ๋ฐ์ดํธ ๋งํผ ๋ฉ๋ชจ๋ฆฌ ํ ๋น | ์ด๊ธฐํ ์ ๋์ด ์์ (์ฐ๋ ๊ธฐ ๊ฐ) |
calloc(n, size) | n๊ฐ ร size ๋ฐ์ดํธ ํ ๋น | 0์ผ๋ก ์ด๊ธฐํ |
realloc(ptr, size) | ๊ธฐ์กด ๋ฉ๋ชจ๋ฆฌ ํฌ๊ธฐ ๋ณ๊ฒฝ | ๋ฐ์ดํฐ ์ ์งํ๋ฉด์ ํฌ๊ธฐ ์กฐ์ |
free(ptr) | ํ ๋นํ ๋ฉ๋ชจ๋ฆฌ ํด์ | ํ์ ํธ์ถ, ์ ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์ ๋ฐ์ |
free ๋ฐ๋์ ํธ์ถNULL ๋ฐํ โ ๋ฐ๋์ ํ์ธ.free(arr);
arr = NULL;ํ๋ก๊ทธ๋จ์ด ๋ฐ๋ก ์ข
๋ฃ๋๋ ๊ฒฝ์ฐ๋ ํ์ํ์ง ์์ง๋ง ์ดํ ๋์์ด ๋จ์์๋ค๋ฉด ์๋ชป๋ ์ฌ์ฉ์ ๋ง๊ธฐ ์ํด ํด๋น ๊ณผ์ ํ์void *memset(void *ptr, int value, size_t num);
ptr์ด ๊ฐ๋ฆฌํค๋ ๋ฉ๋ชจ๋ฆฌ ๋ธ๋ก์ ๋ชจ๋ ๋ฐ์ดํธ๋ฅผ value๋ก ์ฑ์.value๋ ๋ฐ์ดํธ ๋จ์๋ก ํด์๋จ (์: memset(arr, 1, 4) โ ๊ฐ ๋ฐ์ดํธ๋ฅผ 0x01๋ก ์ฑ์)void *memcpy(void *dest, const void *src, size_t num);
src์ ๋ฉ๋ชจ๋ฆฌ ๋ด์ฉ์ dest๋ก ๊ทธ๋๋ก ๋ณต์ฌ.sizeof๋ก ์ ํํ ํฌ๊ธฐ๋ฅผ ๊ณ์ฐํด์ ์ฌ์ฉํด์ผ ํจvoid *memmove(void *dest, const void *src, size_t num);
src์ ๋ฉ๋ชจ๋ฆฌ ๋ด์ฉ์ dest๋ก ๋ณต์ฌ (๊ฒน์น๋ ์์ญ๋ ์์ ํ๊ฒ ์ฒ๋ฆฌ).memcpy๋ณด๋ค ์ฝ๊ฐ ๋๋ฆด ์ ์์ (์์ ์ฑ ๋๊ฐ)memmove ์ฌ์ฉ ๊ถ์ฅ#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
// 1. malloc + memset (์ด๊ธฐํ)
int *arr = malloc(sizeof(int) * 5);
memset(arr, 0, sizeof(int) * 5); // 0์ผ๋ก ์ฑ์ฐ๊ธฐ
// 2. ๊ฐ ์ฑ์ฐ๊ธฐ
for (int i = 0; i < 5; i++) arr[i] = i + 1;
// 3. realloc (ํฌ๊ธฐ ํ์ฅ)
arr = realloc(arr, sizeof(int) * 8);
memset(arr + 5, 0, sizeof(int) * 3); // ์๋ก ๋์ด๋ ๋ถ๋ถ 0 ์ด๊ธฐํ
// 4. memcpy (๋ณต์ฌ)
int *copy = malloc(sizeof(int) * 8);
memcpy(copy, arr, sizeof(int) * 8);
// 5. memmove (๊ฒน์น๋ ์์ญ ์์ ๋ณต์ฌ)
memmove(copy + 2, copy, sizeof(int) * 6);
// 6. ์ถ๋ ฅ
for (int i = 0; i < 8; i++) printf("%d ", copy[i]);
printf("\n");
free(arr);
free(copy);
return 0;
}
| ํจ์ | ์ฉ๋ | ๊ฒน์นจ ๊ฐ๋ฅ? | ์๋ | ์ฃผ์ ํน์ง |
|---|---|---|---|---|
memset | ๋ฉ๋ชจ๋ฆฌ ๋ธ๋ก ์ฑ์ฐ๊ธฐ | N/A | ๋น ๋ฆ | ๋ฐ์ดํธ ๋จ์ ๊ฐ ์ฑ์ |
memcpy | ๋ฉ๋ชจ๋ฆฌ ๋ธ๋ก ๋ณต์ฌ | โ | ๋งค์ฐ ๋น ๋ฆ | ๊ฒน์นจ ์ ์ํ |
memmove | ๋ฉ๋ชจ๋ฆฌ ๋ธ๋ก ๋ณต์ฌ | โ | memcpy๋ณด๋ค ๋๋ฆผ | ์์ ํ ๋ณต์ฌ |
int *arr = malloc(sizeof(int) * 5);
int *arr = (int*)malloc(sizeof(int) * 5);
์ฃผ์ํ ์ด์ :
1. C++ ์์ ํธํ์ฑ
2. ๊ฐ๋ ์ฑ
3. ์ผ๊ด์ฑ
์ฃผ์ํ ์ด์ :
1. C ํ์ค์์๋ ๋ถํ์ํ๋ค
2. ๋ฒ๊ทธ ํ์ง ๋ฐฉํด
3. ์ฝ๋ ๋จ์ํ
Explicit is better than implicit
Trust the machine over the human