반원 블로그

[C 프로그래밍] 동적 메모리_2.sizeof 응용 본문

2017/C 프로그래밍

[C 프로그래밍] 동적 메모리_2.sizeof 응용

반원_SemiCircle 2017. 2. 22. 19:07

이전 포스팅 : http://gosmcom.tistory.com/11



#1 sizeof연산자를 통한 동적 메모리 할당!
sizeof에 A를 넘겨주면 A의 크기를 반환해준다.

sizeof(자료형이름) => 자료형의 크기
sizeof(변수이름) => 변수의 자료형의 크기

즉 int a 의 크기는 sizeof(int) 또는 sizeof(a)가 가능하다. 

보통 전자를 많이 사용한다. 
후자는 연결리스트에 필요한 동적할당에서 구조체의 크기를 구할 때의 sizeof를 빗대어 생각해보자.


#2 왜 굳이 sizeof를 써서 동적 할당을 해야되는가?
이전 포스팅에서 '컴파일러에 따라 자료형 bit가 다르다'는 것을 사례로 들었다.
이번에는 실제 코드를 비교해 살펴보도록 하자.

▶A의 코드 ideone 확인하기


#include <stdio.h>
#include <stdlib.h>

int main(void) {
	int *value;
	value = (int*)malloc(4);
	*value = 100;
	printf("value : %d\n", *value);
}

▶B의 코드 ideone확인하기

#include <stdio.h>
#include <stdlib.h>

int main(void) {
	int *value;
	value = (int*)malloc(sizeof(int));
	*value = 100;
	printf("value : %d\n", *value);
}

보통 출력값도 같고 정상적으로 작동하겠지만 아래와 같은 문제가 발생할 수 있다.

- int 이외의 자료형일 때에는 A 코드가 비정상 동작 할 수 있다.
- 32비트, 64비트 이외의 컴파일러로 컴파일하면 A 코드가 비정상 동작될 수 있다.(예: 16비트 컴파일러)
- 16비트 컴파일러로 컴파일했을 때 불필요하게 2바이트의 메모리가 낭비되는 소스코드가 된다.

이에 반해 B코드는 상수대신 sizeof 연산자를 썼기에, 여러가지 컴파일러 환경에서 모두 적절하게 사용할 수 있는 소스코드가 되었다.


#3 동적 메모리 사용시 주의할 점
- 정확한 크기의 메모리를 할당 받아야 한다
- 사용자가 할당한 동적 메모리는 사용자가 직접 시스템에 반환해야 한다.( JAVA같이 메모리 관리를 자동으로 해주는 언어는 제외한다)

▶ 만일 사용이 끝난 메모리를 시스템에 반환하지 않는다면? 
시스템은 사용자가 메모리를 계속 사용하는 줄 알고 계속 유지한다. (메모리 누수, Memory Leak)

▶ 임시적으로 필요한 메모리를 malloc 으로 계속 해서 할당 받고 반환하지 않는다면? 
사용하지 않는 메모리가 늘어나 메모리 부족으로 프로그램을 더 이상 사용할 수 없는 상태가 된다.

//동적 메모리 해제
#include <stdlib.h> //필요한 헤더파일
void free(메모리주소); //사용하는 함수

즉 메모리 누수를 방지하려면 할당과 해제는 항상 같이 사용해야한다.

연습 3_1

#include <stdio.h>
#include <stdlib.h>
 
int main(void) {
	int *value;
	value = (int*)malloc(sizeof(int)); //메모리 할당
	*value = 100;
	printf("value : %d\n", *value);
	free(value); //메모리 해제, free하지 않으면 메모리 누수가 발생한다.
}


#4 동적 메모리 배열
지금까지 동적 메모리와 할당, 해제를 배웠으니 동적 메모리 배열을 만들어보자
- 배열의 길이만큼 메모리 공간을 malloc으로 얻어낸 후 사용한다
- '배열의 길이*자료형의 크기' 만큼의 메모리를 얻어서 사용한다.

연습 4_1 - 동적 메모리 공간에 배열을 선언하고 그 공간을 사용하는 프로그램 (ideone확인하기)


#pragma warning(disable 4996)
#include <stdio.h>
#include <stdlib.h>//동적 메모리 사용을 위한 헤더 선언
 
int main(void) {
	int count, input, i; //프로그램에서 사용할 변수 선언
	int *array; //동적 배열에 사용할 포인터 선언

	printf("원하는 배열의 길이 : "); 
	scanf("%d", &count); //배열 길이를 count 변수에 저장

	array = (int*)malloc(sizeof(int) * count); // 'int의 사이즈*count' 만큼 메모리 할당, int형으로 지정

	//배열에 사용자가 입력한 값을 저장
	for(i=0;i<count;i++){
		printf("%d 번째 수 입력 : " , i);
		scanf("%d",&input);
		*(array+i)=input;
	}

	//배열에 저장된 값 출력
	for(i=0; i<count; i++){
		printf("*(array+%d) = %d\n", i, *(array+i));
	}

	free(array);
}

//입력: 5 4 3 2 1 5 일때의 출력 결과 
*(array+0) = 4
*(array+1) = 3
*(array+2) = 2
*(array+3) = 1
*(array+4) = 5


#5 동적 메모리 정리

- 필요한 헤더 파일  : #include <stdlib.h> 
- 동적 메모리 할당 

함수 원형 : void* malloc(사용할 메모리 양)
사용 예 : int *ptr; 
ptr = (int *)malloc(sizeof(int)); 

- 동적 메모리 해제

함수 원형 : void free(메모리주소); 
사용 예 : free(ptr); 

- 동적 메모리 할당에 필요한 자료형의 크기 구하기 

sizeof(자료형이름) = 자료형의 크기 
sizeof(변수이름) = 변수의 자료형의 크기

- 할당된 동적 메모리 사용시 주의점
사용자가 할당한 동적 메모리는 free 함수를 통해 반환해야 한다. 그렇지 않으면 메모리 누수현상이 일어난다.


Comments