LetITGo

C언어 구조체와 포인터의 적용, 동적 메모리 할당을 하는 이유는? 본문

전공지식/자료구조와 알고리즘

C언어 구조체와 포인터의 적용, 동적 메모리 할당을 하는 이유는?

올라프의 취미 2020. 8. 30. 10:30
728x90

안녕하세요 이번에는 지난번에 알아본 구조체와 포인터를 어떻게 자료구조에서 적용하는지에 대해서 알아보겠습니다. 또한, 동적 메모리 할당이 무엇인지에 대해서 알아보겠습니다.

 먼저 구조체와 포인터를 잘 모르는 사람들은 복습하거나 새로 배우고 오는 것을 추천합니다.

2020/08/28 - [전공지식/자료구조 와 알고리즘] - C언어 포인터 Pointer에 대해 알아봅시다

 

C언어 포인터 Pointer에 대해 알아봅시다

안녕하세요 오늘은 C언어에서 포인터에 대해서 알아보겠습니다. 포인터는 저도 솔직히 많이 어려워했던 부분이라서 열심히 공부했습니다. 처음에는 쉽게 배우면 앞으로 프로그래�

letitgo01.tistory.com

2020/08/29 - [전공지식/자료구조 와 알고리즘] - c언어 - 구조체 Structure, 구조체 배열에 대해서 알아봅시다.

 

c언어 - 구조체 Structure, 구조체 배열에 대해서 알아봅시다.

 오늘은 구조체(Structure)에 대해서 알아보겠습니다. 구조체는 여러 변수를 하나로 묶어서 하나의 정보로 통합하는 형태를 의미합니다. 예시처럼 한 학생의 정보에 이름, 학번, 성적

letitgo01.tistory.com

 

구조체에도 포인터를 적용 할 수 있습니다. student라는 타입의 구조체를 선언하였습니다. 구조체의 멤버로는 학번을 의미하는 정수형 변수 num, 성적을 의미하는 실수형 변수 grade가 있습니다.

 메인 함수에서는 구조체 변수 s와 구조체 포인터 변수 *ps를 선언하였습니다. 구조체 포인터 ps는 구조체 변수 s의 주소를 가지고 있습니다.
 포인터를 이용하여 구조체의 멤버를 접근할 때는 ->을 이용하여야 합니다. 그래서 ps->num이라는 것은 ps가 가리키는 구조체 변수 s의 멤버인 학번 num을 의미합니다. 그래서 ps-> num = 17이라는 것은 s의 학번은 17이고 ps -> grade = 4.2는 s의 성적은 4.2라는 것을 의미합니다.

 구조체의 포인터를 선언하고 포인터를 이용하여 구조체의 멤버를 접근하는 것은 매우 중요합니다. 나중에는 구조체 배열을 적용하여 포인터로 구조체 배열의 멤버를 대입하거나 비교할 수 있어야 합니다.

 이제 동적 메모리 할당이 무엇인지 말씀드리겠습니다.
프로그램이 메모리를 할당받는 방법은 두 가지가 있습니다. 하나는 정적 메모리 할당이고 두 번째는 동적 메모리 할당입니다.

 정적 메모리 할당이란 메모리의 크기가 프로그램이 시작하기 전에 정해지고 프로그램이 실행되는 도중에는 크기가 변경될 수 없습니다.
 그래서 처음에 계획한 크기보다 큰 입력이 있으면 처리할 수 없어서 오류가 일어나고 계획한 크기보다 작으면 메모리 공간이 남아서 메모리의 낭비가 일어납니다. 이제 동적 메모리 할당이 무엇인지 말씀드리겠습니다.
프로그램이 메모리를 할당받는 방법은 두 가지가 있습니다. 하나는 정적 메모리 할당이고 두 번째는 동적 메모리 할당입니다.

 정적 메모리 할당이란 메모리의 크기가 프로그램이 시작하기 전에 정해지고 프로그램이 실행되는 도중에는 크기가 변경될 수 없습니다.
 그래서 처음에 계획한 크기보다 큰 입력이 있으면 처리할 수 없어서 오류가 일어나고 계획한 크기보다 작으면 메모리 공간이 남아서 메모리의 낭비가 일어납니다.

 두 번째 방법인 동적 메모리 할당은 프로그램을 실행하면서 메모리를 할당하는 것을 의미합니다. 필요한 만큼 컴퓨터로부터 할당받고 남는다면 반납하기 때문에 메모리를 좀 더 효율적으로 관리하고 사용할 수 있습니다.

 이제 동적 메모리 할당을 하는 법에 대해서 알아보겠습니다.
기본형태는 사진에 있는 것과 같습니다. 동적 메모리를 할당받고 메모리를 사용하고 반납하는 형태입니다. malloc( )이라는 말이 메모리를 할당받는다는 말입니다. free( )가 메모리 할당을 해제하여 반납한다는 말입니다. size of()가 변수, 타입의 크기를 반환하는 뜻입니다. 이때 크기는 바이트 단위입니다.

 메모리 할당받는 것에 대해서 자세히 알아보겠습니다. malloc( )에서 괄호 안에는 바이트 단위의 크기가 들어갑니다. 그래서 그 크기만큼의 메모리를 확보합니다. 앞에 char, int, sturct는 자료형으로 첫 문장은 100바이트로 100개의 문자를 저장할 메모리를 확보하고 두 번째는 정수 1개를 저장할 메모리를 확보합니다. 세 번째는 stu라는 구조체에 해당하는 메모리를 할당받습니다.

메모리 해제 하는 법도 같습니다. 해제할 대상을 free( )의 괄호 안에 넣어주면 됩니다.

 동적 메모리 할당의 예제를 한번 보겠습니다.
 학생들의 정보를 담는 구조체를 선언하였고 메인 함수에서는 구조체 Student의 포인터 변수 *p를 선언하고 p를 할당받습니다. 만약 할당받지 못한다면 "메모리를 할당받을 수 없습니다."고 출력하고 1을 반환하고 종료합니다. 할당받았다면 2명의 학생 정보를 변경하고 동적 메모리를 해제합니다.

struct Student {
int number;
char name[10];
};
int main() {
struct Student *p;
p = (struct Student *)malloc( 2*sizeof(struct Student) );
if( p == NULL ){
printf( "메모리를 할당받을 수 없습니다.\n") ; return 1 ;
}
p->number=1;
strcpy(p->name,"Park");
(p+1)->number=2;
strcpy((p+1)->name,"Kim");
free(p);
return 0;
}


 이렇게 하면 메모리를 좀 더 효율적으로 관리하는 프로그램을 만들 수 있습니다.


 오늘은 지난번에 알아보았던 포인터와 구조체를 함께 사용해보았습니다. 생각보다 어려운 개념들을 공부한 것 같습니다. 하지만 자료구조에서는 꼭 필요한 내용입니다. 정확하게 아는 것이 중요할 것 같습니다.

 다음에는 리스트에 대해서 알아보겠습니다.

Comments