⭐️ 9.11. Common Memory-Related Bugs in C Programs

  • 9.11.1 허용되지 않은 주소값을 참조하는 행위 아직 할당받지 않은 주소공간을 참조하려 한다거나 커널 영역에 해당하는 가상주소를 참조하려는 경우 MMU에 의해 Exception이 발생할 수 있습니다.
  • 9.11.2. 초기화되지 않은 메모리를 읽는 행위 초기화되지 않은 전역변수가 담긴 BSS영역은 프로그램이 로드될때 0으로 초기화됩니다. 하지만 동적으로 할당받는 힙 영역은 암시적으로 0으로 초기화되지 않습니다.
  • 9.11.3. 스택 버퍼 오버플로우를 일으키는 행위 스택영역은 함수가 호출될때 얼마나 그 크기가 늘어날지 (stack pointer가 값이 줄어들지) 컴파일 시간에 계산을 완료합니다. 프로그래머 실수로 스택영역을 초과하는 위치에 값을 쓰게 된다면 이전 스택에 저장된 메모리가 훼손될 것입니다.
  • 9.11.4. 잘못된 크기를 할당받는 경우 객체와 포인터를 헷갈리는 케이스입니다. 예를 들어 이차원 배열을 동적할당받을때 int * 배열을 할당받을 것을 int 배열을 할당받아버리는 경우, 포인터 사이즈와 int 사이즈가 다르면 문제가 발생할 수 있습니다.
  • 9.11.6. 객체가 아닌 포인터에 연산을 하는 경우 연산자 우선순위를 제대로 숙지하지 못해 *ptr--와 같은 실수를 범할 수 있습니다. 이 경우 *(ptr--)수행하여 포인터의 위치가 바뀌어버릴 수도 있습니다. 따라서 괄호를 적절하게 사용하는 것이 중요합니다.
  • 9.11.7. 포인터 대수연산을 실수하는 경우 모든 포인터는 자기가 가리키는 타입의 크기를 알고 있습니다. 따라서 32비트 정수형 포인터에 ++ 연산을 수행하면 4 바이트 뒤의 메모리를 가리키게 되고 64비트 정수형 포인터에 ++ 연산을 수행하면 8바이트 뒤의 메모리를 가리키게 됩니다.
  • 9.11.8. Dangling Pointer 스코프를 벗어나면 해제가 되는 지역변수의 주소값을 리턴하게 되는 경우 댕글링 포인터가 되어 정의되지 않은 행동을 수행하게 됩니다.
  • 9.11.9. Use After Free free한 공간을 참조하고 사용하는 행위 또한 정의되지 않은 행동을 수행하게 됩니다.
  • 9.11.10 메모리 누수 동적으로 메모리를 할당한 뒤 제때 해제하지 않는 경우 발생합니다. 오랜시간 작동해야 하는 프로그램의 경우 가용 메모리 부족으로 종료될 수도 있습니다.