본문 바로가기

Programming/C++

04. C언어의 메모리 구조

메모리 공간 할당은 컴퓨터가 할당 해주는 것이 아니라 운영체체 가 메모리 공간을 할당 해준다 



------------------------------

정적 할당 :
     정적 할당이란 컴파일-타임 , 스타트-타임 시에 메모리에 할당할 메모리양 을 미리 필요한 만큼 계산하여 할당하는 방식이다
     정적 할당 시 에 메모리를 미리 계산 하여야 하기 때문에 정확한 수치로 인하여 메모리 할당이 필요하다
     배열(Array)을 정적 할당 시에 첨자(arr[상수]) 로 는 변수 를 쓸수 없다 변수를 쓴다면 첨자로 쓰인 변수가 프로그램 실행중에 어떠한 문제로 인하여 
     변수 값이 바뀔수 있는 상황을 가지고 있고 컴파일-타임 , 스타트-타임 시에 정확하게 변수의 실제 값을 알수가 없어서이다

동적 할당 : 
     동적 할당 이란 컴파일-타임 , 스타트-타임 아닌 프로그램이 실중일때 (런-타임)에 유동적으로 메모리를 할당하는 방식을 말한다
     정적 할당 시에 배열 선언 시 첨자 로 변수를 쓸수 없지만 동적 할당시에는 메모리 할당이 유동 적이어서 변수로 첨자를 쓸수있다
     첨자 를 변수를 써서 매모리 할당을 하기 때문에 어떠한 수를 넣어도 할당이 가능하다  

------------------------------

데이터 영역 (정적 할당) :
     전역변수(함수 밖에 선언한 변수) , Static(스태틱)변수 들은 프로그램 시작과 동시에 할당 되고 프로그램이 종료 되어야 메모리가 소멸한다 

스택 영역 (정적 할당) :
     함수 호출시 생성 되는 지역변수 매개변수(파라미터 변수, 함수 인자) 가 저장되는영역이다 함수 호출이 완료되면 메모리가 소멸 된다

힙(Hear) 영역 (동적 할당) :
     프로그래머가 관리하는 영역
     할당 해야 할 메모리의 크기를 런-타임(프로그램이 실행 되는 동안에) 시에  결정 해야 하는 경우 힙(Hear)영역에 
     malloc() 함수를 이용하여 메모리 동적 할당 한다.
     # 힙(Hear)영역 에 메모리 할당 후 에 는 사용자(개발자)가 직접 free() 함수를 이용 하여 메모리 해제 하여야 한다
     
     동적 할당한 변수는 []첨자 를 이용한 배열 형식으로 활용 해야 한다     
     *pd++ 연산 시 free() 호출 시 오류 발생
     
     
동적 할당 예 :
     int i =5;
     int *num = (int*) malloc(sizeof (int) * i );
     malloc()함수는 void* 형 포인터 을 리턴 한다 그래서 원하는 타입 으 로 캐스팅 을 하여야 한다
     for (int j=0; j<i ; j++)
     {
          num[j ] = j;
     }
     for (int k=0; k<i ; k++)
     {
          printf("%d" ,num[ k]);
     }
     free(num );
     // 표시01234
     
동적 할당 시 오류 예 :
     for (int k=0; k<i ; k++)
     {
          printf("%d" ,*num++); 포인터 연산 방식은 가능 하나
          // 표시01234
     }
     free(num ); 메모리 해제 시 오류가 난다

하지만
     int *pi num;
     for (int i= 0; i <sss; i++)
     {
               printf(" pi = %d \n" ,*pi++);
           // 표시01234
     }
     free(num); 메모리 해제 시 에러 안남
이런 방식은 에러가 나지 않는다
이유를 생각 해보았 을 땐...

동적 할당 을 해서 배열을 힘 메모리에 놀려도 num 은 힘에 할당 된
포인터 상수 이지 않을까 싶다
일반 배열 이름 처럼...
일반 배열 이름 은 포인터 상수 이다 와 같은 동격??


------------------------------

malloc , calloc , realloc 예 :
int i = 5;
int *num1 = (int*) calloc(i ,sizeof( int));
char *num2 = (char*) malloc(sizeof (char)* i);
printf("%d \n" ,sizeof( num1)); //4 포인터형크기
printf("%d \n" ,sizeof( num2)); //4 포인터형크기
printf("%d \n" ,sizeof(* num1));//4 int 형크기
printf("%d \n" ,sizeof(* num2));//1 char 형크기
free(num1 );
free(num2 );
// 동적할당시malloc , calloc , realloc void* 형포이터를반환하기때문에
// 좌측의피연산자는포인터타입이되는것이다 32bit 운영체체에서는포인터
// 크기는4 바이트이다 64bit8 바이트이다

int *ar = (int*) malloc(sizeof (int)*5);
ar[4] = 100;
ar = (int *)realloc( ar,10*sizeof (int));
ar[9] = 200;
printf("%d , %d \n" ,ar[4], ar[9]);// 100 , 200
free(ar );