일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 티스토리
- CS
- Kotlin
- c++
- doit코틀린프로그래밍
- Programming
- Win32
- Windows
- 포인터
- 배열
- 김성엽
- Tips강좌
- 프로그래밍
- Desktop
- c#
- 백준
- Tips프로그래밍강좌
- 알고리즘
- 함수
- Javascript
- tipssoft
- 지식나눔강좌
- 연산자
- 이지스퍼블리싱
- 리뷰
- c
- Visual Studio
- Direct2D
- VS ERROR
- 문법
- Yesterday
- Today
- Total
F.R.I.D.A.Y.
sizeof 연산자의 오용 본문
이전 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)으로 선언되어 있기 때문입니다.
해결법
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
'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 |