14.04.28 21:10

2014. 4. 28. 21:17

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력해주세요.

메모리 동적 할당

i2sec/Secure C 2014. 4. 23. 21:08

1.메모리 동적 할당이란?

내가 원하는 만큼의 공간을 Heap 이라는 곳에 할당하여 사용하는 것


2.선언 방법

기본형 : void* malloc(size_t size);

->size_t = typedef unsigned int size_t => 부호가 없는 정수 즉, 양수를 선언하는 자료형이다.

->인자 부분에는 양수 형태로 만들고자 하는 공간의 크기를 입력

->자료형이 "void*" 형이기 때문에 사용시 캐스팅을 사용해야 한다.


* malloc(); 함수는 할당한 공간의 주소를 리턴한다.


3.사용하는 이유

1.원하는 만큼 공간을 사용할 수있다.

2.메모리 관리가 효율적이다.

ex) char stu[100]; 이라고 '100'크기의 공간을 선언했다.

그러나 실질적으로는 '30'만큼의 공간만 사용한다. 그러면 '70'이라는 공간이 남게 되어 메모리가 낭비된다.

그러므로 메모리 동적 할당으로 필요한 만큼만 할당해서 사용한다.




4.메모리 동적 할당 사용

1.헤더파일

malloc();함수를 사용 하기 위해서는 <stdlib.h> / <malloc.h> 헤더파일이 필요하다(둘 중에 하나 선택 사용)

2.free(); 함수

메모리를 할당하고 사용 후 pc에게 공간 사용을 종료하겠다고 이야기 해주는 기능

사용 형태 : free(할당된 공간의 시작 주소);

#include <stdio.h>

#include <stdlib.h>


int main(void)

{

int *ptmp = malloc(10);    -예제1

int *ptmp = (int*) malloc(10);    -예제2

  free(ptmp);    -예제3

return 0;

}

(예제1)

이 코드를 실행하면 ERROR가 난다.

이유는 malloc(); 함수는 "void*"형태이기 때문에 캐스팅을 하고 사용해야 되는데 캐스팅을 하지 않았기 때문이다.


(예제2)

malloc();함수의 올바른 사용이다.

캐스팅 할때에는 할당한 공간에 담을 data의 형태에 맞게 캐스팅한다.

만약 포인터 연사자 '*'을 뺄 경우 할당된 공간의 주소가 아니라 값이 전달되므로 ERROR가 난다.


(예제3)

인자로 ptmp를 넣은 이유는 ptmp가 할당한 공간의 시작주소를 가지고 있기 때문이다.


*"free();"함수로 같은 공간을 두번 닫았을 경우

처음 'A'라는 공간을 할당하여 사용 후 종료했다.

그리고 'B'라는 공간을 할당하고 'A'가 있던 공간에 할당 되었다

'B' 공간을 사용 중에 'A'라는 공간을 종료하지 않았다고 착각해서 'A'공간을 닫았을때 

'A'공간이 아니라 'B'공간이 닫히게 되어서 ERROR가 발생한다.



5.메모리 동적 할당 사용2

<예제 코드>

#include <stdio.h>

#include <stdlib.h>

int main(void)

{

int i = 0;

int *ptmp = (int*) malloc(10);

char *pch = (char*) malloc(20);

ptmp[0] = 10;

ptmp[1] = 20;

printf("Sum = %d\n",ptmp[0] + ptmp[1]);

for(i ; i<10 ; i++)

{

pch[i] = 0x61 + i ;

}

printf("%s\n",pch);

free(ptmp);

free(pch);

return 0;

}


<실행 결과>






*문자열 뒤에 이상한 값이 나오는 이유

 ->문자열 출력시 NULL문자까지 출력한다. 그런데 NULL문자는 "pch"맨끝에 존재 하고 나는 pch[0] ~ pch[9]까지 입력 하였다.

   그러면 pch[10] ~ pch[18]까지는 쓰레기 값이 들어 있으므로 이상한 값이 출력된다.

 ->해결방법

   1.pch[10]에 0을 입력해준다 => pch[i] = 0;(for문이 끝나면 i의 값은 10을 가지고 있기때문에)

   2.공간을 크기 조정 => char *pch = (char*)malloc(10);


*공간의 낭비를 없애기 위한 방법

지금 내가 필요한 만큼의 공간을 할당해서 사용하고 있지만 ptmp가 가르키는 곳에는 2byte, pch가 가르키고 있는 곳에는 10byte가 낭비되고 있다.

이것을 없애기 위해서는 malloc();함수의 인자값을 변경할 필요가 있다.


인자 : 자료형의 크기 * 데이터의 갯수

malloc(sizeof(int)*2);   /    malloc(sizeof(char)*10);


(그냥 처음 인자는 8, 두번째 인자는 10을 넣으면 안되냐는 생각을 할 수도 있지만 만약에 세월이 지나서 자료형의 크기가 변하게 되서 이 코드를 사용하면 제대로 동작하지 않는다

그런데 이렇게 코드를 작성하면 자료형의 크기가 변해되더라도 사용가능 하다.)


*ptmp[3] = 30; 이라고 소스를 추가 했을때

현재 ptmp가 가르키고 있는 곳의 크기는 10byte이다. 그 곳에는 현재 4byte 짜리 ptmp[0], ptmp[1] 2개가 존재해서 8byte를 사용중이다.

그런데 ptmp[3]을 추가하게 되면 남은 공간은 2byte데 4byte를 추가할려고 하므로 ERROR가 발생한다.


*할당한 공간 늘리기 -> realloc();

->사용 형태 : realloc(늘릴 곳의 주소, 변경할 크기);

->공간 늘림 : 원래 입력되어 있던 값은 그대로 있고 공간만 늘어남

<소스 추가>

  realloc(ptmp, sizeof(int)*5);

realloc(pch, sizeof(char)*20);

<실행 결과>



->공간 줄임 : 원래 있던 값 중 공간안에 있을 수 있는 만큼만 남고 없어짐 

<소스 추가>

realloc(ptmp, sizeof(int));

realloc(pch, sizeof(char)*5);

<실행 결과>








출처 == i2sec

'i2sec > Secure C' 카테고리의 다른 글

14.04.28 21:10  (0) 2014.04.28
2014-04-23 AM12:46  (0) 2014.04.23
주의 사항!!!  (0) 2014.04.18
하... 역시나...  (0) 2014.03.31
START...  (0) 2014.03.28

2014-04-23 AM12:46

2014. 4. 23. 00:53

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력해주세요.

주의 사항!!!

2014. 4. 18. 22:04

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력해주세요.

하... 역시나...

2014. 3. 31. 22:30

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력해주세요.

START...

2014. 3. 28. 19:56

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력해주세요.