컴퓨터 개론 및 실습 11. 동적 메모리 할당
메모리의 구성 메모리 공간을 나눠놓은 이유는 커다란 서랍장의 수납공간이 나뉘어 있는 이유와 유사하다. 메모리 공간을 나눠서 유사한 성향의 데이터를 묶어서 저장을 하면, 관리가 용이해지고 메모리의 접근속도가 향상된다.
메모리 영역별로 저장되는 데이터의 유형 실행할 프로그램의 코드가 저장되는 메모리 공간. CPU는 코드 영역에 저장된 명령문을 하나씩 가져다가 실행 전역변수와 static 변수가 할당되는 영역. 프로그램 시작과 동시에 할당되어 종료 시까지 남아있는 특징의 변수가 저장되는 영역 프로그래머가 원하는 시점에 메모리 공간에 할당 및 소멸을 하기 위한 영역 지역변수와 매개변수가 할당되는 영역 함수를 빠져나가면 소멸되는 변수를 저장하는 영역
동적 할당(Dynamic Allocation) 정의 실행시간에 변수 또는 배열에 메모리를 할당 변수배열은 초기 선언 시 정적 상수의 값으로 할당해야 하나 동적메모리할당을 이용하여 실행 중 배열의 크기를 지정할 수 있음. 동적 메모리 할당은 메모리를 효율적으로 사용하기 위해서 사용한다. 동적 공간 할당 또는 동적 공간 확보라고도 하며 실행 시 메모리 공간을 해제 하는 것을 동적 메모리 해제 라고 한다. 동적 할당된 변수 또는 배열은 free 함수를 이용하여 사용 후 해제해야 함.
학생 수를 입력 받아서 학생 수 만큼의 배열을 생성하고자 하는 경우 아래와 같이 코드를 작성하면 에러가 발생. 배열의 크기는 상수로만 지정할 수 있다. 배열은 스택에 생성되므로 기본적으로 1MB이상의 메모리 공간을 사용할 수 없지만 동적으로 메모리를 할당받는 경우는 힙을 사용하므로 크기는 일반적으로 무한대로 설정할 수 있다. 즉 사이즈가 큰 변수를 만들 때도 동적 메모리 할당을 사용해야 함.
힙 영역의 메모리 공간 할당과 해제 반환형이 void형 포인터임에 주목! malloc & free 함수 호출의 기본 모델
malloc 함수의 반환형이 void형 포인터인 이유
동적 메모리 할당 형식 자료형은 포인터 변수의 자료형 Malloc 의 반환형이 void 형이므로 직접 사용은 불가능하고 형 변환을 이용하여 사용해야 한다. 포인터 변수 = (자료형*) malloc (메모리 크기)
동적 메모리 해제 형식 동적 메모리 할당 해제 형식 free(포인터변수) free(i) 동적 메모리 공간을 할당 받아 사용하고 사용이 끝나면 해제해 주는 것이 좋다. 그렇지 않으면 그 공간은 사용할 수 없는 공간이 됨. 주의 할 점은 동적 메모리 공간이 해제되면 포인터변수가 가리키는 공간이 해제된다는 사실. 포인터 변수는 함수 내에서 선언되어 있으면 함수가 종료될 때 소멸되게 된다. 위 2개의 함수는 stdlib.h 파일에 정의.
동적 메모리 할당과 해제 주석 처리 된 부분을 해제하면 에러가 발생 포인터 변수는 선언된 후 동적 메모리 할당을 받거나 다른 변수의 주소를 가리키지 않으면 바로 사용할 수 없다. 단 문자열 상수는 예외 - 문자열 상수는 그 자체로 주소이기 때문이다. 프로그램이 실행될 때 ap 변수에 4바이트의 메모리를 할당하고 프로그램이 종료되면 메모리 공간을 해제 하라는 프로그램. 동적 메모리 공간을 할당 받을 때 malloc()의 안에 직접 상수를 대입하는 것은 별로 바람직하지 않은 방법이다. sizeof(int)의 형태로 입력해주는 것이 바람직하다. int형의 크기가 변하더라도 영향을 받지 않기 때문이다.
메모리 동적할당 사용과 그렇지 않은 경우 동적 메모리 할당을 적절히 이용하면 동일한 메모리 공간을 여러 가지 용도로 사용할 수 있다!!
주의할 점 메모리 공간을 해제한 변수에는 값을 저장해선 안됨! 공간을 해제한 포인터에는 값을 대입할 수 없도록 NULL을 지정해 주는 것이 바람직 하다.
동적 메모리 할당과 해제
동적 메모리 할당을 이용한 배열 생성 동적 메모리 할당은 배열 대신 사용할 수 있다. 배열은 처음부터 메모리 할당을 받아야 하므로 사용자의 입력을 받아서 메모리 할당을 할 수 없지만 동적 메모리 할당을 이용해서 메모리를 할당하면 동적으로 배열을 생성할 수 있다.
동적 메모리 할당을 이용한 배열 생성 위의 프로그램을 배열을 이용해서 jumsu를 생성하려면 몇 명의 데이터가 입력될지 모르므로 최대한의 데이터를 생각해서 배열을 생성해야 한다. 하지만 동적 메모리 할당을 이용하면 적절한 크기의 배열을 생성할 수 있다.
반드시 동적 할당이 필요한 경우
기타 동적 메모리 할당 관련 함수 calloc malloc는 초기화를 수행하지 않으므로 쓰레기 값으로 초기화가 되고 사용형식 포인터변수 = (포인터자료형 *)calloc(개수,메모리크기) malloc는 초기화를 수행하지 않으므로 쓰레기 값으로 초기화가 되고 calloc는 모든 메모리 공간을 0으로 초기화를 수행하므로 0이 출력되게 된다.
realloc 메모리를 재할당 받을 때 사용하는 함수. 메모리를 재할당 받더라도 이전의 데이터는 소멸되지 않고 그대로 보존 된다. 기존의 데이터를 유지하면서 재할당 시작 주소에는 기존의 메모리 주소 변수를 대입한다. 사용형식 포인터변수 = (자료형 *)realloc(시작주소,메모리크기);
메모리 재 할당 malloc를 이용해서 재할당을 받게 되면 이전 데이터가 모두 소멸되지만 realloc를 이용해서 재 할당을 받게 되면 이전 데이터를 유지 하면서 재 할당 받게 된다.
구조체 동적 할당 ‘구조체’ 역시 사용자가 만든 하나의 데이터 타입 1차원 구조체 배열 선언 Malloc 함수를 이용하여 arr을 위한 공간 할당
구조체 동적 할당
Node 동적 할당을 통하여 사용자가 원하는 크기의 입력을 다룰 수 있게 되었다고 해도 문제는 존재한다. 1000개의 데이터 공간을 만들었는데 1개의 데이터를 추가 해야 한다면, 그것 때문에 1001 개의 공간을 새로 만들어야 한다. *이럴 경우 Node 를 사용한다.
Node 의 모양 C 코드로 나타낸 노드
Node 의 사용법 각각의 노드는 하나의 데이터를 가지고 있음. 데이터를 하나 더 추가하고 싶다면, 마지막 노드에 새 노드를 하나 이어주면 된다!
노드의 삽입 기존의 배열에서 불가능 했던 ‘배열 중간에 새 데이터 삽입’ 이 가능해진다.
새 노드를 만드는 함수
노드를 파괴하는 함수
Thank you -*