프로그래밍시스템 개발자, 백엔드 개발자

C++에서 undefined behavior(정의되지 않은 동작)란 무엇이며, 왜 위험한가요? 예를 들어 설명하고 회피하는 방법을 설명하세요.

Hintsage AI 어시스턴트로 면접 통과

답변.

Undefined behavior(UB, 정의되지 않은 동작)은 코드에서 표준이 정의하지 않은 행동입니다. 이 경우 컴파일러는 어떤 결정을 내려도 됩니다: 프로그램은 서로 다른 플랫폼, 컴파일러에서 다르게 작동할 수 있으며, 심지어 핵전쟁을 일으킬 수도 있습니다(형식적으로!). UB 사용은 C++에서 가장 위험한 실수입니다.

UB 예시:

  • 배열의 경계를 넘는 접근
  • 초기화되지 않은 변수 사용
  • 같은 메모리 영역을 두 번 해제하기
  • dangling pointers(무효 포인터) 사용
int* p = new int[2]; delete[] p; int x = p[1]; // UB: 해제 후 메모리 접근

UB 방지를 위한 방법:

  • 변수를 항상 초기화하세요;
  • 배열/컨테이너의 경계를 확인하세요;
  • 수동 메모리 관리를 피하고 smart pointers를 사용하세요.

트릭 질문.

다음 코드에서 무슨 일이 일어날까요?

int a = 42; int b = a++ + ++a;

b의 값은 무엇인가요?

답변:

이 코드는 UB를 발생시키며, 이는 변수 a를 조작하는 동안 연산 간에 순서 포인트(sequence points)가 없기 때문입니다. 표준은 특정 결과를 보장하지 않으며, 컴파일러는 어떤 결과든 생성하거나 예기치 않은 코드를 생성할 수 있습니다.

주제에 대한 미세한 어두운 역사로 인한 실제 오류 사례.


이야기 데이터 저장 시스템 프로젝트에서 한 개발자가 저수준 함수에서 배열의 경계를 넘는 접근을 저질렀습니다. UB는 특정 사용자 데이터에서만 나타났고, 파일 구조를 손상시키고 고객 데이터 손실을 초래했습니다.


이야기 마이크로컨트롤러 프로젝트에서 초기화되지 않은 변수를 읽는 구문이 발견되었습니다. 테스트는 통과하였으나, 장치 출시 1년 후에 UB로 인해 발생한 사용 중의 우연한 오류가 발견되었습니다: 변수는 때때로 잡음 값을 포함하고 있었습니다.


이야기 대규모 오픈 소스 프로젝트에서 코드의 서로 다른 부분에서 두 번 해제되는 디스크립터가 발견되었습니다. 이 UB는 처음에는 매우 드물게 발생했지만, 새로운 운영 체제 버전에서 잦은 비정상 중단으로 이어졌습니다.