메모리 동적 할당

 

 

동적 할당 함수

 

- 정적 할당 : 프로그램 작성 시 필요한 기억공간의 크기를 결정하는것

 

- 동적 할당 : 메모리 낭비의 최소화를 위해 입력되는 데이터에 맞게 기억공간을 할당하는 것

 

- 동적할당을 하기 위해 malloc함수 사용(stdlib.h 헤더파일에 존재)

ex)

int* ip;

ip = (int*)malloc(sizeof(int));    //기억공간을 동적으로 할당받아 포인터 변수에 연결

 

- 프로그램 실행 시 메모리의 일정한 영역인 기억부류는 4가지가 있다.

     코드영역        :    실행 파일을 위한 영역

        스택           :    자동 변수 영역

기타 데이터 영역  :    외부 변수, 정적 변수 영역

          힙            :    동적 할당 메모리 영역

 

- 자동변수의 경우 함수가 리턴되면서 자동으로 기억공간을 회수하지만 동적할당은 그렇지 않다.

  따라서 특정 함수에 구속받지 않고 위치값만 알면 어디서나 참조가 가능하다.

  만약 동적할당된 메모리를 반납하려 한다면 free함수 사용한다.(stdlib.h 헤더파일에 존재)

ex)

free(ip);    //할당 받은 기억공간 반환

 

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

int main(){
 int a = 10;
 int* ap;

 ap = (int*)malloc(sizeof(int));
 *ap = 20;
 printf("%d\n", a + *ap);
 free(ap);
 return 0;
}

결과 

 

- 메모리 할당 함수는 힙 영역에 원하는 크기의 메모리가 존재하지 않을 경우 널포인터를 반환

  따라서 프로그램이 중단되지 않게 하기 위해 malloc함수 호출 후 검사하여 널포인터인지 확인해야 함

 

예제 16-1) 일교차 출력 프로그램

최고기온과 최저기온을 저장할 기억공간을 동적으로 할당 후 일교차 출력

#include <stdlib.h>

int main(){
 
 int* ap;
 int* bp;

 ap = (int*)malloc(sizeof(int));
 bp = (int*)malloc(sizeof(int));
 

if(ap==0 && bp==0){    //malloc함수 호출 후 널포인터인지 확인

  printf("메모리가 부족합니다.\n");

}

else{
  printf("최고기온과 최저기온을 입력하세요\n");
  scanf("%d %d", ap, bp);

  printf("일교차는 %d도 입니다.", *ap - *bp);

}

 return 0;

 

결과

 

 

 

동적 할당 기억공간의 활용

 

- 주로 많은 기억공간을 한꺼번에 할당 받아서 배열로 사용하는 것이 효율적

 

- 할당 받은 기억공간의 시작 위치만 포인터변수로 가리키게 하면 포인터변수를 배열명으로 사용하여 배열과 같이 활용

 

- 동적 할당을 사용하여 문자열 처리하기

① 문자열을 입력받기 위해 충분히 큰 크기의 문자 배열 선언

② 문자열 입력 받기

③ 입력된 문자열의 길이를 계산해 크기에 맞게 기억공간을 동적으로 할당

④ 문자열을 할당받은 기억공간에 복사

 

#include <stdlib.h>
#include <string.h>


int main(){
 
 char temp[80];    //①
 char* str[3];
 
 for(int i=0;i<3;i++){
  printf("문자열을 입력하세요 : ");
  gets(temp);    //②
  str[i] = (char*)malloc(strlen(temp)+1);    //③
  strcpy(str[i], temp); //④
 }
 
 for(int i=0;i<3;i++){
  printf("%s\n", str[i]);
 }
 
 for(int i=0;i<3;i++){
  free(str[i]);
 }


 return 0;
}

결과

 

 

- 주의할 점은 포인터 변수나 포인터 배열을 자동변수로 선언하면 쓰레기값이 존재하게 되므로 선언과 동시에 널포인터로 초기화해주는 것이 좋다.

ex)

선언시 : char* str[100]={0};

저장된 문자열 출력시:

for(int i=0;str[i]!=0;i++){

printf("%s\n", str[i]);

}

 

예제 16-2) 행렬의 합

1  2   3  4        12 11 10 9         13 13 13 13

5  6   7  8    +   8  7  6   5    =   13 13 13 13

9 10 11 12        4  3   2  1         13 13 13 13    만들기

#include <stdio.h>
#include <stdlib.h>
int main()
{
 int* ap[3];
 int* bp[3];
 int* cp[3]; //행렬의 합
 for(int i = 0; i < 3; i++) { //메모리 동적 할당을 해준다
  ap[i] = (int *) malloc(sizeof(int));
  bp[i] = (int *) malloc(sizeof(int));
  cp[i] = (int *) malloc(sizeof(int));
 }
 for(int i = 0; i < 3; i++) {
  for(int j = 0; j < 4; j++) { // 각 요소의 합을 cp행렬에 저장한다.
   ap[i][j] = 4*i + 1*(j+1);
   bp[i][j] = 12 - 4*i - 1*j;
   cp[i][j] = ap[i][j] + bp[i][j];
  }
 }
 for(int i = 0; i < 3; i++) {
  for(int j = 0; j < 4; j++) {
   printf("%d\t", cp[i][j]);
  }
  printf("\n");
 }
 return 0;
}

결과

 

 

 

메인함수의 전달인자

 

- 명령행에서 프로그램을 실행시킬 때는 프로그램의 이름 외에도 프로그램에 필요한 정보를 함께 입력할 수 있는데 이들을 명령행 전달인자 라고 한다.

 

- 메인함수의 전달인자를 사용하는 방법

#include <stdio.h>

int main(int argc, char** argv){
 for(int i=0;i<argc;i++){
  printf("%s\n", argv[i]);
 }
 return 0;
}

위의 코드를 작성 후 cmd창을 켜 위의 코드가 저장되어 있는 경로로 이동한다.

그리고 (파일명) (전달인자) (전달인자) 를 입력한다.

결과

 

 

 

기타 동적 할당 함수

 

- calloc함수 : 배열을 할당 받고 초기화 한다.

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

int main(){
 double* ap;
 ap=(double*)calloc(5, sizeof(double));
 for(int i=0;i<5;i++){
  printf("%lf\n", ap[i]);
 }
 return 0;
}

결과

 

 

- realloc함수 : 기억공간의 크기를 조절한다.

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

int main(){
 int* ip;
 int size = 5;
 int cnt = 0;
 int num;
 
 ip=(int*)calloc(size, sizeof(int));
 while(1){
  printf("양수를 입력하세요");
  scanf("%d", &num);
  if(num<=0) break;
  if(cnt<size){
   ip[cnt++]=num;
  }
  else{
   size+=5;
   ip=(int*)realloc(ip, size*sizeof(int));
   ip[cnt++]=num;
  }
 }
 for(int i=0;i<cnt;i++){
  printf("%5d", ip[i]);
 }
 free(ip);
 return 0;
 
 return 0;
}

결과

 

프로그램을 종료시키지 않는 한 계속 양수를 입력할 수 있다.

 

 

 

 

'Programming > C' 카테고리의 다른 글

C언어 정리(9)  (0) 2015.08.09
C언어 정리(7)  (0) 2015.08.07
C언어 정리(6)  (0) 2015.08.06
C언어 정리(5)  (0) 2015.07.20
C언어 정리(4)  (0) 2015.07.20

+ Recent posts