F.R.I.D.A.Y.

sizeof 연산자의 오용 본문

DEV/C C++

sizeof 연산자의 오용

F.R.I.D.A.Y. 2019. 6. 17. 09:06
반응형

 이전 sizeof 연산자에 대한 포스트는 이 포스트를 위한 선행 단계라고 봐도 무방하겠네요. 이번엔 sizeof 연산자를 사용해선 안 되는 부분을 다뤄봅니다.

 

※ 이 포스트는 Visual Studio 2019 Community v16.1.2. 에서 테스트되었습니다.


메모리 크기는 반환하지 않습니다

 우리가 이전에, malloc() 함수 등을 사용하는 동적 할당이라는 방법을 배우기 전엔 배열을 사용했습니다. 이렇게 컴파일 전에도 크기를 알 수 있는 배열을 정적 배열(static array)라고 부르는데, 이 정적 배열을 이용하면서 사용했던 방법은 동적 배열에선 이용할 수 없습니다. 다음 코드를 보겠습니다.

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

int main(void) {

	int* arr = (int*)malloc(sizeof(int) * 10);


	for (int i = 0; i < sizeof(arr) / sizeof(int); ++i) {
		arr[i] = i + 1;
	}


	for (int i = 0; i < sizeof(arr) / sizeof(int); ++i) {
		printf("%d ", arr[i]);
	}

	free(arr);

	return 0;
}

 이전 포스트의 sizeof를 이용한 배열 길이를 알아내는 코드에서, 정적 배열을 동적 배열로 바꾼 코드입니다. 그런데 문제가 있습니다. 분명 for 반복이 10번 이루어질 것이라고 생각했는데, 한 번밖에 이루어지지 않습니다. 정적 배열을 사용할 때는 sizeof의 결과로 40이 나왔으니 이번에도 40이 나와야 하는데 확인해보면 4로 나옵니다.


sizeof의 오용

 먼저 아래 코드를 돌려봅니다.

#include <stdio.h>

int main(void){
	
    int *p = NULL;
    
    printf("%d\n", sizeof(p));
    
    return 0;
}

 위에서 사용했던 논리대로라면 p는 아무것도 없으니 0이 나와야 하겠지만, 4가 나옵니다. 왜 그럴까요? 우리는 p가 가리킨 메모리가 아닌 p 자체를 sizeof연산자로 연산했습니다. 따라서 p 자체의 크기가 반환된 것이죠.

 더불어 *p를 피연산자로 넘기더라도 4가 나옵니다. 이는 NULL이 ((void *)0)으로 선언되어 있기 때문입니다.

vcruntime.h에 NULL이 선언되어있습니다.


해결법

 

Plan1. 크기를 따로 저장하기

 대부분 동적 할당을 사용할 때는 사용자로부터 크기를 받거나, 다른 함수에서 파라미터로 할당받을 크기를 받습니다. 이는 반복 작업이 몇 번 이루어져야 하는지 알고 있다는 뜻입니다.

 

Plan2. 동적 할당 받은 메모리 크기를 구하는 함수 사용하기

 표준은 아닙니다만, MSVC에서는 _msize()라는 함수를 제공합니다. 힙 공간에 할당된 메모리의 크기를 반환해주는 함수입니다. 아래와 같이 사용할 수 있습니다.

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

int main(void) {

	int* arr = (int*)malloc(sizeof(int) * 10);

	for (int i = 0; i < _msize(arr) / sizeof(int); ++i) {
		arr[i] = i + 1;
	}


	for (int i = 0; i < _msize(arr) / sizeof(int); ++i) {
		printf("%d ", arr[i]);
	}

	free(arr);

	return 0;
}

 다음은 sizeof 연산자와 _msize() 함수의 비교입니다.

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

int main(void) {

	int* arr = (int*)malloc(sizeof(int) * 10);

	printf("%d %d", _msize(arr), sizeof(arr));
	// Output: 40 4

	free(arr);
	return 0;
}

참고

MS Docs - _msize() 함수 (바로가기)

 

# index

728x90
반응형

'DEV > C C++' 카테고리의 다른 글

함수 인자로 단항연산자 사용하기  (0) 2019.06.25
C 스타일의 문자열 관리 방식  (0) 2019.06.25
sizeof 연산자  (0) 2019.06.17
Snake with Windows API  (0) 2019.06.08
define VS typedef  (0) 2019.05.21
Comments