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

VS ERROR C6011 : NULL 포인터 'variable'을(를) 역참조하고 있습니다. 본문

DEV/Tip

VS ERROR C6011 : NULL 포인터 'variable'을(를) 역참조하고 있습니다.

F.R.I.D.A.Y. 2019. 4. 23. 08:33
반응형

 Visual Studio가 2017에서 2019로 넘어오며 인텔리센스가 더욱 정교화됐습니다. 이러한 인텔리센스의 업그레이드로 2017에선 하지 않던 경고가 2019에선 하는 경우가 많아졌는데, 이번에 소개할 경고도 같은 경우입니다.

C6011, NULL 포인터 'p'을(를) 역참조하고 있습니다.

 이번 포스팅에서는 C6011 경고가 왜 생기고 어떻게 하면 사라지게 할 수 있는지 알아봅니다.


원인. 잠재적 버그 가능성

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

int main(void) {

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

	for (int i = 0; i < 10; ++i) {
		p[i] = i + 1;
	}
	
	free(p);

	return 0;
}

 대부분의 컴퓨터에서는 문제가 발생하지 않을 코드이지만, 이 코드도 결국 잠재적인 문제를 일으킬 수 있는 코드입니다.

 malloc 함수는 일반적으로 성공하는 케이스가 많지만, malloc 함수가 실패하게 되면 아래 p[i] = i + 1; 코드는 문제가 일어납니다. 메모리 할당이 되지 않은 상태에서 특정 메모리에 접근하려고 했으니까요.

 2019 업데이트에서는 이런 잠재적 버그 또한 잡을 수 있도록 인텔리센스가 고도화되었네요. 이전엔 코드 분석을 진행해야 이런 경고가 떴다고 하는데 많은 부분을 인텔리센스로 가져왔습니다.


해결. 실패에 대한 예외 코드 작성하기

 이 경우에는 malloc 함수 등이 실패했을 때를 대비한 예외 코드를 작성해주면 됩니다. 코드 스타일은 여러가지가 있겠습니다만, 아래처럼 코드를 작성하시면 됩니다.

// 1번 코드
#include <stdio.h>
#include <stdlib.h>

int main(void) {

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

	if (p != NULL) { // malloc 함수는 실패시 NULL을 반환합니다.
		for (int i = 0; i < 10; ++i) {
			p[i] = i + 1;
		}
		free(p);
	}

	return 0;
}

 모든 경우에 대해 if문으로 묶어서 처리를 해주어야 하느냐구요? 아닙니다. 아래처럼 작성할 수 있습니다.

// 2번 코드
#include <stdio.h>
#include <stdlib.h>

int main(void) {

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

	if (p == NULL) return -1;

	for (int i = 0; i < 10; ++i) {
		p[i] = i + 1;
	}

	free(p);

	return 0;
}

 굳이 if문으로 묶지 않더라도 이런 식으로 처리함으로써 코드의 들여 쓰기를 줄일 수 있습니다. 이 프로그램의 경우 메모리를 받아서 값을 입력하는 것으로 작업을 완료하기 때문에 정상적으로 메모리 할당을 못 받은 경우엔 return -1로 프로그램을 바로 종료시켜버렸습니다.

 

# 2019.12.19. 추가

 프로그램을 작성할 때, 중괄호 등이 많아짐에 따라 들여쓰기를 하게 되는 것은 어쩔 수 없습니다. 그러나 너무 많은 들여쓰기는 오히려 코드 가독성에 독이 됩니다. 따라서 중괄호는 묶을 곳은 묶되, 불필요한 곳까지 묶지는 않는지 생각하는 것이 좋습니다. 위 코드 경우에도 p 변수가 NULL값인지만 확인하면 되므로 1번째 코드보다는 2번째 코드처럼 작성하는 것이 좋다고 생각합니다.

728x90
반응형
Comments