본문 바로가기

C언어/복습

[C언어]DAY16_동적 할당, 동적 배열

동적메모리 할당(dynamic memory allocation)

동적메모리 할당이란 ? : 실행 도중(run-time)시 사용할 메모리 공감을 할당
  /반대개념: 정적메모리 할당: 컴파일시 사용할 메모리 공간 할당. 변경불가.


Heap메모리 Stack메모리 구분.
1. 컴파일시 메모리 공간 할당영역:
 1) 데이터영역(전역변수, 리터럴(상수"hello word")저장공간)과 
 2) 스택영역에 할당되는 메모리 공간

2. run-time시 메모리 공간 할당영역
 Heap영역: 실행도중 사용자가 직접 메모리 할당.

//malloc() 함수:  <stdlib.h>안에 선언되어있음.
  메모리 할당시 호출하는 함수
  반환값으로 주소값을 반환. 주소값: 힙영역에 할당된 메모리 공간의 첫번째 주소
  따라서 malloc()의 반환값은 포인터로 받아야 한다.
  포인터로 힙영역의 메모리 공간에 접근해야 한다.
//free()함수:
  힙영역에 할당된 메모리 공간을 다시 운영체제로 반환. 반드시 해야힘. 에러는 나지 않음.
  메모리 누수가 발생(memory leakage)

 

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

//1. 포인터 변수 선언: 할당된 메모리 주소를 저장할 포인터
int main(){
     int a;
     int b;
     int*p_num = NULL;

//2. 메모리 할당
//sizeof를 사용하여 필요한 메모리 공간을 계산한다.
//할당할 byte수와 저장할 값의 타입과 동일하게 강제형변환(캐스팅casting)을 꼭 해줘야 함.
     p_num =(int*) malloc(sizeof(int));
     //p_num = &a 같음
     *p_num = 10;


     //sizeof로 할당된 공간의 사이즈를 알 수 없다. 포인터 변수의 사이즈: 4
     printf("%d %d %d %d %d\n", &a , &b ,p_num, sizeof(p_num), * p_num);

//3. 할당받은 메모리를 반환!!
     free(p_num);
}

 


//배열을 동적으로 메모리 할당하여 사용.

//int type 배열


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

int main(){
	//int type
	int size = 0;
	int i =0;
	int a =0;

	//1. 포인터 선언
	int *p_num = NULL;
	
	//배열의 크기를 사용자에게 받는다.
	printf("배열의 크기를 입력하세요.\n");
	scanf_s("%d", &size);
	printf("배열의 크기는 %d입니다\n", size);
	
	//2. 사용자가 정한 갯수만큼 메모리 할당.
	p_num = (int*)malloc(sizeof(int)*size);
	
	//int 타입 동적 배열에 사용자로부터 받은 값을 저장.
	//*연산자를 사용하여 접근
	printf("정수 %d개 입력하세요.\n", size);
	for(i =0; i<size; i++){
		scanf_s("%d", &p_num[i]);
		//scanf_s("%d", p_num+i);
	}

	//저장한 후 출력
	for(i =0; i<size; i++){
		printf("%2d ", *(p_num+i));
	}
	printf("\n");
	//arr[i] = *(arr+i)
	//[]연산자를 사용하여 접근 11부터 20까지 저장후 출력
	for(i =0; i<size; i++){
		p_num[i]= i+11;
	}
	for(i =0; i<size; i++){
		printf("%d ", p_num[i]);
	}

	//3. 메모리 반환
	free(p_num);



 

//문자열(char 의 배열)를 저장하기 위한 메모리 동적 할당

//char type 배열의 memory allocation

//문자열을 다룰 때는 항상 NULL을 생각해야 함! : 필요한 size +1

//"hello"를 저장하고 싶으면 메모리 6개

 


 

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

int main(){
	//포인터 선언
	char* p_char = 0;
	int size = 0;
	//사용자에게서 문자열의 길이를 입력받아서 처리한다.
	printf("저장하고 싶은 문자열의 길이를 입력하세요.\n");
	//scanf_s("%d", &size, sizeof(size));
	scanf("%d", &size);
	printf("문자열의 길이는 %d입니다.\n", size);

	printf("%d %d\n", sizeof(p_char), size *sizeof(char)); //포인터 변수의 사이즈: 4
	//사용자에게 이름을 입력받는다.
	printf("이름을 입력하세요. \n"); //null공간 확보해야 하므로

	//메모리 할당
	p_char = (char*)malloc((size+1) *sizeof(char));

	//scanf_s("%s", p_char, sizeof(p_char));
	scanf_s("%s", p_char, (size+1) *sizeof(char)); 
	//scanf_s는 자동으로 문자열 마지막에 null을 붙여준다.
	//따라서 문자열의 길이는 1이 추가된다. 즉, 메모리 할당은 스트링길이보다 1이 더 필요함.
	printf("%s가 입력되었습니다.\n", p_char);

	//메모리 반환
	free(p_char);
}

과제

 

//double을 받아서 int로 변환하는 프로그램.

//double type의 배열을 선언하고자 한다.

//dynamic memory allocation을 이용하여 사용자에게 갯수를 입력받고

//그 갯수만큼 실수를 입력받은 뒤, 실수를 int로 변환하여 출력하세요.

 

//double을 받아서 int로 변환하는 프로그램.
//double type의 배열을 선언하고자 한다.
//dynamic memory allocation을 이용하여 사용자에게 갯수를 입력받고
//그 갯수만큼 실수를 입력받은 뒤, 실수를 int로 변환하여 출력하세요.

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



void main() {
	double* p_num = 0;
	int i = 0;
	int size = 0;

	printf("배열의 크기를 입력하세요.\n");
	scanf_s("%d", &size);
	printf("입력하신 배열의 크기는 %d입니다.\n", size);

	p_num = (double*)malloc(sizeof(double)*size);

	printf("실수 %d개를 입력하세요.\n", size);
	for (i = 0; i < size; i++) {
		scanf_s("%lf", p_num + i, sizeof(char)*size);
	}
	printf("\n");

	for (i = 0; i < size; i++) {
		printf("%.2lf ", p_num[i]);
	}
	printf("\n");

	for (i = 0; i < size; i++) {
		printf("%d ", (int)p_num[i]);
	}

	free(p_num);

}

 


첫 번째 코드작성에서 오류가 있던 이유.

//이미 double로 할당되어 있어서 위의 함수에서 int로 변환 불가능함.