realloc함수에 대한 설명을 찾아보면 다음과 같은 과정으로 작동한다고 한다.
1. 동적할당된 메모리 크기를 변경해 재할당함 (기존 주소일수도 있고, 새로운 주소일 수도 있음)
2. (새로운 주소에 할당한 경우) 기존 주소에 있던 값을 새로운 주소에 복사하고 원래 주소는 할당해제함
얼마나 많이 메모리 주소를 옮겨갈까 궁금해서 아래 코드로 테스트를 해보았다.
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#include <stdio.h>
#include <Windows.h>
int main(void) {
int arraysize = 10;
int i = 0;
char* test = (char*)malloc(sizeof(char) * arraysize);
int plus = 10;
float chk = 0;
for (; i < 10000; i++) {
arraysize += plus;
char* temp = NULL;
char* bfch = NULL;
temp = realloc(test, sizeof(char) * arraysize);
if (temp != NULL) {
if (test == temp) {
printf("재할당size: %5d byte, 주소: %p, 메모리주소 안바뀜\n", arraysize, test);
}
else {
bfch = test;
test = temp;
printf("재할당size: %5d byte, 주소: %p, 메모리주소 바뀜\n", arraysize, test);
chk++;
}
}
else printf("메모리 재할당에 실패했습니다.\n");
}
printf("========================================================================\n");
printf("테스트 종료.%5d byte씩 증가 %5d번 재할당할 경우\n\n메모리주소 바뀔 확률: %.2lf%%\n"
, plus, i, (double)chk / i * 100);
printf("========================================================================\n");
free(test);
_CrtDumpMemoryLeaks();
system("pause");
return 0;
}
생각보다 그렇게 많이 옮겨 다니지 않는다.
그리고 CRT 디버그 라이브러리를 사용해서 _CrtDumpMemoryLeaks(); 함수로 확인해봤는데 메모리 누수도 없었다. 그런걸 보니 주소를 옮긴경우 예전 주소는 잘 할당해제 되었나보다.
얼마전까진 realloc 대신 malloc+memcpy+free 조합을 사용했는데, 이정도 효율이라면 realloc 쓰는것도 괜찮을것 같다는 생각이든다..
다만 realloc 사용 시 주의할 것은 기존에 할당된 메모리를 가리키는 포인터에 바로 realloc 리턴값을 대입하면 안된다는 것. NULL 반환시 기존에 할당된 메모리에 접근할 방법이 없어지기 때문이다.
그래서 위 코드 처럼 임시 포인터에 realloc 리턴값을 대입하고 NULL이 아닌 경우에 원래 포인터에 주소값을 대입해줘야 한다.
또 다른 하나는 malloc+memcpy+free 조합은 100% 주소를 옮기지만 realloc은 1. 주소를 옮긴 경우 2. 안옮긴 경우 두가지 경우의 수가 있으니 거기에 대한 예외처리가 필요할 수 있다는 것이다.
'프로그래밍 > C' 카테고리의 다른 글
C ] 가변인자 함수 만들기, 가변인자 출력함수 만들기 (0) | 2022.08.12 |
---|---|
[ Visual Studio ] CRT 라이브러리로 메모리 누수 탐지하기 (0) | 2022.05.02 |
[ C언어 ] scanf의 리턴값 (0) | 2022.04.27 |
[ C언어 ] scanf 공백 ( 띄어쓰기 ) 포함 원하는 길이 만큼만 문자열 입력 받는 방법. (0) | 2022.04.27 |
scanf , scanf_s " %d "로 정수 입력 받으려다 문자(열)이 잘못 들어왔을 때 무한루프에 빠지는 문제 / 문장 씹히는 문제 해결 (0) | 2022.04.27 |