C언어 배열 free - ceon-eo baeyeol free

안녕하세요! 오늘은 6번째 시간입니다. 7번째 시간에는 구조체를 다루도록하고 8번째 시간에는 포인터를 다루도록 하겠습니다. 근데 이번 시간에 포인터와 연관되는 것이 나오는데 아주 간략하게만 설명하도록 하겠습니다.

먼저 소스코드를 보시겠습니다.

Line 3 : b라는 변수가 int형 포인터로 선언이 되었습니다. 이 말이 무슨 뜻인가 하면 배열을 배웠던거 기억 나시나요? 배열로 선언된 변수는 0번째 원소의 주소 값으로 그 배열의 주소를 찾아냅니다. 왜냐하면 0번째 원소부터 순서대로 마지막 원소까지 있기 때문인데요. 포인터는 조금 다릅니다. 이 포인터라는 변수는 int 자료형을 가진 변수를 가리키는 역할을 합니다. 말 그대로 주소값을 저장해놓고 만약 컴파일 시에 그 주소값에 해당하는 값이 필요하다면 그 주소값에 해당하는 값을 사용할 수 있도록 가리키는 역할을 합니다.

Line 7 : 이제 이번 시간에 배울 내용인 malloc함수에 대해서 나왔는데요. 나름 간단합니다. b가 무슨 자료형을 가진 변수인지 (int*)라고 표시를 해주고 이제 오른쪽 함수 사용할 때에도 (int *)를 사용하여 b와 같은 자료형들로 동적 할당을 받을 수 있게 해주고 malloc 내부의 매개변수는 int 자료형의 size(4byte) * 할당받을 개수 로 사용합니다. 만약 5를 입력하면 20byte만큼의 공간이 생길 것이고 6을 입력한다면 24byte만큼의 공간이 b에게 주어지겠네요.

Line 8 : b가 할당 받은 메모리의 크기를 출력해주는 것입니다. 출력을 하게 될 경우 int 자료형의 크기 : 4byte * 입력받은 개수 = 총 할당받은 크기를 출력하도록 하는 것입니다.

Line 9~13 : 먼저 for문이 돌아가는데 i가 0번째 원소부터 N-1번째 원소까지 반복을 합니다. 그 동안에 내부 동작은 *는 가리킨다라고 읽어주시면 됩니다. i가 0번째 원소일 때 for문의 동작을 보시면 'b+0이 가리키는 값을 0으로 집어넣어라.' 라는 의미가 됩니다. 따라서 i가 0일 때  *(b+i)를 출력한다면 b+0이 가리키는 값을 0으로 집어넣었으니 0이 출력이 될 것입니다. 마찬가지로 for문이 동작하여 i가 1일 경우에는 *(b+1)에 1을 집어넣었으니 1이 출력이 될거고 for문 동작이 N-1번째 까지 가게 된다면 *(b+N-1) = N-1; 이니까 출력을 하게 될 경우 N-1이 될 것입니다.

Line 14 : free( 동적할당 받은 변수 ) 를 사용하시게 된다면 메모리에 있던 그 할당받은 내용들을 지워줍니다. 이게 메모리 관리 문제에 직면할 수 있으니 malloc()함수를 사용한다면 free를 해줘야겠군.이라고 생각하시면 됩니다.

출력창을 보실까요?

네 일단 N으로 4를 입력 받았고 b가 할당받은 메모리는 int 자료형의 크기(4byte) * N(4)를 해줘서 16byte다. 라고 출력이 되었고 아래에 차례대로 Line 9~13 에 했던대로 0,1,2,3 즉, N-1까지의 출력이 되었다는 것을 알 수 있습니다.

이 함수는 동적으로 메모리를 관리할 때에 사용하기 편하게 해줍니다. 정적인 메모리 할당보다 동적인 메모리 할당이 훨씬 편합니다. 왜냐하면 100개를 할당 받는데 그 이상으로 할당을 해줘야할 경우에는 오버플로우나 100개는 필요없고 한 50개만 할당을 받으면 되는데 100개를 할당해서 메모리 낭비를 시킬 수가 있습니다. 따라서 유연하게 malloc()함수를 사용해주신다면 좀 더 효율적인 코드를 짜실 수 있으실 겁니다. 나중에 좀 심화된 예제를 올릴테니 그 때 확실히 이해하셨으면 좋겠습니다!

이 레퍼런스의 모든 내용은 여기를 기초로 하여 작성하였습니다.

아직 C++ 에 친숙하지 않다면 씹어먹는 C++ 은 어때요?

stdlib.h 에 정의됨

void free(void* ptr);

메모리를 해제한다

이전에 malloc 혹은 calloc, realloc 등으로 할당된 메모리를 해제해서, 나중에 다시 사용될 수 있게 합니다.

만일 ptr 이 위의 함수들도 할당된 메모리를 가리키지 않는다면, 무슨일이 일어날지는 아무도 모릅니다(undefined behavior).

만일 ptr 이 널 포인터라면, 위 함수는 아무것도 하지 않습니다.

기존에 malloc, callor, realloc 으로 할당된 메모리의 시작점을 가리키는 포인터

없음

/* free example */ #include <stdlib.h> /* malloc, calloc, realloc, free */ int main() { int *buffer1, *buffer2, *buffer3; buffer1 = (int*)malloc(100 * sizeof(int)); buffer2 = (int*)calloc(100, sizeof(int)); buffer3 = (int*)realloc(buffer2, 500 * sizeof(int)); free(buffer1); free(buffer3); return 0; }

실행 결과

실행 결과

(잘 실행 된다.)
  • malloc : 메모리를 할당한다.

  • calloc : 0 으로 초기화된 메모리를 할당한다.

  • realloc : 메모리를 재할당 한다.

포인터와 배열의 관계

📌 포인터와 배열은 밀접한 관계를 갖고 있으나, 분명한 차이점이 있다.

📌 배열은 선언하게 되면 기본적으로 배열 자기 자신의 시작 주소를 갖고 있다.

#include <stdio.h> int main() { char str[100]; printf("str의 주소 : %p\n", &str); printf("str의 값 : %p\n", str); printf("입력 : "); scanf("&s", str); printf("출력 : %s\n", str); return 0; }#include <stdio.h> int main() { char str1[10] = "Hello"; char* str2 = "Abcde"; /*printf("atr1 : %s\n", str1); printf("str1 : %s\n", str2);*/ str1[0] = 'B'; str2[0] = 'Z'; printf("str1 = %c%c%c%c%c\n",str1[0], str1[1], str1[2], str1[3], str1[4]); printf("str2 = %c%c%c%c%c\n", str2[0], str2[1], str2[2], str2[3], str2[4]); return 0; }

동적 할당

  • 메모리 공간을 원하는 시점에 원하는 크기 만큼 할당 받고 그 공간을 사용 후, 원하는 시점에 해제하는 방식
  • 메모리 공간을 할당 받을 때는 malloc()함수를 사용해서 할당 받을 수 있다.
  • 이 때, 반드시 stdlib.h 헤더파일을 선언해주어야 한다.
  • malloc() 함수의 원형 : 주소를 저장할 변수 = malloc(크기);
  • 동적 할당을 통해서 할당 받은 메모리 공간은 Heap 영역에 해당한다.
  • 동적 할당 받은 메모리 공간을 해제할 때는free(해제할 공간의 주소); 형식으로 해제할 수 있다.
  • 한 번의 동적 할당에는 반드시 한 번의 동적 해제가 진행되어야 한다.
  • malloc()함수에서 크기를 넘겨 줄 때에는 기본적으로 sizeof()연산자를 이용해서 넘겨준다.
#include <stdio.h> #include <stdlib.h> int main() { int* ptr; ptr = (int*)malloc(4); //void 포인터 형태의 값을 반환 *ptr = 10; printf("출력 : %d\n", *ptr); free(ptr); return 0; }#include <stdio.h> #include <stdlib.h> int main() { int* ptr; ptr = (int*)malloc(sizeof(int)*34); ptr[0] = 10; ptr[1] = 20; printf("츨력 : %d %d\n", ptr[0], ptr[1]); free(ptr); return 0; }

Toplist

최신 우편물

태그