관리 메뉴

꿈꾸는 개발자

C언어 동적할당/포인터/메모리/가변배열(포인터)-정리/동적 배열! 본문

프로그래밍언어/C언어

C언어 동적할당/포인터/메모리/가변배열(포인터)-정리/동적 배열!

rickysin 2022. 2. 13. 19:10
  • 동적할당: 동적인 메모리 할당으로 stack이 아닌, heap영역에 할당되는 형태를 말한다

visual studio에서 작성할 경우, 파일 확장자가 '.c'여야 한다. 'cpp'의 경우 에러가 발생할 수 있음! 

#include <stdio.h>
#include <stdlib.h>    // malloc, free 함수가 선언된 헤더 파일

int main()
{
    int num1 = 20;    // int형 변수 선언
    int *numPtr1;     // int형 포인터 선언

    numPtr1 = &num1;  // num1의 메모리 주소를 구하여 numPtr에 할당

    int *numPtr2;     // int형 포인터 선언

    numPtr2 = (int*)malloc(sizeof(int));    // int의 크기 4바이트만큼 동적 메모리 할당

    printf("%p\n", numPtr1);    // 006BFA60: 변수 num1의 메모리 주소 출력
                                // 컴퓨터마다, 실행할 때마다 달라짐

    printf("%p\n", numPtr2);     // 009659F0: 새로 할당된 메모리의 주소 출력
                                // 컴퓨터마다, 실행할 때마다 달라짐

    free(numPtr2);    // 동적으로 할당한 메모리 해제

    return 0;
}

같은 메모리 공간이더라도, 그 구조가 stack과 heap으로 구별된다. (그리고 스탭, 힙의 위치와 커지는 방향은 운영체제 및 플랫폼에 따라 따름) ->heap의 경우 메모리 해제를 해야한다. (free(변수명);)의 형태를 띤다. 

 

- 메모리 해제를 안 할 경우, 시스템의 메모리가 부족하게 되어, 운영체제가 프로그램을 강제 종료하거나, 메모리 할당에 실패하게 된다. 메모리 해제를 하지 않아, 메모리 사용량이 증가하는 현상을 메모리 누수(memory leak)라 한다. 

 


  • 가변배열-포인터+동적할당 사용: 

int Num[size(입력 받은 값)]의 경우 visual studio에서 컴파일 에러가 발생한다. 따라서, 이러한 방법으로는 가변 배열을 사용할 수 없다.  

- 자료형 *변수명 =(*자료형-heap영역에 할당하는 자료형 설정?)malloc(sizeof(자료형)*크기); 형태로 동적할당해서 가변배열처럼 사용이 가능하다! 

스택 영역

해당 영역은 컴파일 시점에 결정되는 영역이다. 스택 영역의 함수가 종료하게 되면, 할당된 메로리를 반환하게 된다. 

 

힙 영역

해당 영역은 프로그래머에 의해서 실행시점에서 결정된다. 스택 영영과 달리, 힙 영역은 낮은 주소에서 높은 주소로 할당됨, 따라서, 운영체제의 경우에 따라 무한 재귀함수에 의해 힙영역이 침범을 당하면 스택 오버플로우가 발생할 수 있음. 반대의 경우 힙 오버플로우가 발생! 

 

데이터 영역 

해당 영역은 정적변수, 전역변수, 구조체 등 함수 외부에서 선언되는 변수들이 메모리 할당된다. 

 

코드 영역

해당 영역에는 프로그램의 실행 명령어들이 존재한다. 

 

 

Malloc의 경우 heap 영역에 데이터를 할당하는 형태로 배열과 연결해서 사용하면,

#include<stdio.h>
#include<windows.h>
#include<stdlib.h> //malloc 포함

int main() {

	//int(4바이트)크기의 메모리를 * 4만큼 heap영역에 할당한 것이다!
	int* test_malloc = (int*)malloc(sizeof(int) * 4);


	int arr_size; //동적할당+배열!
	scanf_s("%d", &arr_size);
	int* test2_malloc = (int*)malloc(sizeof(int) * arr_size);
	//이런식으로 int *arr=new int[arr_size]처럼, 활용이 가능하다!



	return 0;
}

calloc: 할당된 메모리를 전부 0으로 초기화하는 것!

realloc: 할당된 메모리를 다시 할당할 때 사용한다. 

 


  • calloc을 사용한 동적 배열의 활용:
#include<stdio.h>
#include<stdlib.h>
int main() {

	int i; 
	int* a;
	int na;
	puts("요소의 개수");
	scanf_s("%d", &na);

	a = (int*)calloc(na, sizeof(int));

	for (int i = 0; i < na; i++) {
		printf("a[%d]: ", i);
		scanf_s("%d", &a[i]);//이런식으로 동적 배열처럼, 접근이 가능함!
	}
	putchar('\n');

	for (int i = 0; i < na; i++) {
		printf("a[%d]: %d",i, a[i]); putchar('\n');
	}
	free(a);
	return 0;
}

이처럼, calloc을 통해 배열처럼, 할당한 후 접근 자체도 배열처럼, 데이터 접근이 가능하다! (언제나 배열은 주솟값이란 것을 잊으면 안된다!)

 

 

자료출처:

-https://reakwon.tistory.com/20

 

[C언어] 동적 메모리 할당의 세가지 방법 malloc, calloc, realloc

동적 메모리 할당 우리는 이제껏 메모리를 할당할때 정적으로 할당했습니다. 어떤 것이냐면 int arr[100]; 이렇게 할당을 했었죠. 뭐 문제없습니다. 실행도 잘 되구요. 하지만 이런 상황은 조금 불

reakwon.tistory.com

-코딩도장: C언어