'혼자 공부하는 C언어' 8-1강 확인문제 코딩
'1 2 3 1 2 3 1 2 3' 순으로 출력되도록 배열(Array)을 사용해서 빈칸을 코딩해 보자.
배열(Array)은 파이썬에서는 동적배열이 가능하다. List 구문으로 파이썬의 막강한 배열 함수들을 이용가능하나, 속도가 느리다. 이산수학이나 머신러닝을 위한 언어로 파이썬이 널리 쓰인다. 왜냐면 개발자 생태계에서 유용한 수학 라이브러리가 많기 때문이기도 하다.
어쨌든 위의 소스 코드는 학교에서 배운 % (Mod*)라는 나머지값을 구하는 연산자를 활용해 규칙적인 수열을 출력할 수 있다.
* Mod: 수학 및 프로그래밍에서 나머지 연산자 %는 주로 나머지 연산자 (Remainder Operator) 또는 모듈로 연산자 (Modulo/Modulus Operator)라고 부름. 흔히 'mod'라고 줄여서 읽으며, 정수 나눗셈의 나머지를 구하는 데 사용됨.
상세 호칭 및 특징
수학 용어 Modulo/Modulus Operator (모듈로/모듈러스 연산자): 보통 a % b는 "a mod b"로 읽음.
Remainder Operator (나머지 연산자): 프로그래밍(Python, C 등)에서 주로 쓰이는 명칭으로, 나눗셈 후 남은 나머지를 구한다는 의미를 강조함.
특징: 주로 정수 정수 나눗셈에서 활용되며, 짝/홀수 구분, 배수 확인, 주기적인 패턴(예: 0~5 반복)을 만들 때 유용함.
아래 소스 코드처럼 배열의 각각의 요소(Element) 중, 초기화하지 않은 배열( ary[4] )을 출력시키면, 메모리의 알 수 없는 가비지(번역하면 '쓰레기' 값이 뜬다. 아래 출력값에서 '2'. 리버싱에서 사용하지 않고 지연시키기 위한 용도의 스택, NOP(No Operation)과 비슷하다.
더 나아가 만약, 선언한 배열의 엘러먼트의 개수를 벗어나는(오버 플로) 배열( ary[5] )을 출력시키면, 스택* 메모리의 경곗값을 벗어나서 흘러넘친다고 해서 '스택 오버플로우' 경고를 보일 수 있다. 소스코드에서 실행 후, 해당 코드 라인(16행)의 오른쪽에 그러한 경고성 메시지가 떴다(노란색 점선 박스 안).
warning: array index 5 is past the end of the array (that has type 'int [5]‘) {-Warray-bounds].
제미나이에게 해석해 달라고 하니, 아래와 같이 문제를 정의해 줬다.
상황: int [5]라는 코드는 정수 5개를 담을 수 있는 칸을 만들었다는 뜻입니다.
문제: 프로그래밍(C, C++ 등)에서 인덱스는 0부터 시작합니다. 따라서 5칸짜리 배열의 인덱스는 0, 1, 2, 3, 4까지입니다.
원인: 현재 코드에서 5번 인덱스(실제로는 6번째 칸)를 읽거나 쓰려고 시도했기 때문에, 컴퓨터가 "허용된 범위를 벗어났다"라고 경고를 보내는 것입니다.
* 스택(stack) 참조
이러한 메모리 경곗값에 대한 C언어의 배열에서 발생가능한 취약점을 미연에 방지할 수 있는 솔루션을 제미나이에게 물어봤다.
아래는 macOS(Tahoe 26.3.1) OS 환경에서 터미널(버퍼오버플로 취약점에 대한 설정은 아주 오래전부터 디폴트로 설정되어 있으므로, 그냥 Clang으로 컴파일한 취약한 normal.a 어셈블리어와 취약점 보호 설정을 한 protected.a 어셈블리어의 차이를 비교해 봤다. 보호 설정(flag 구문 : -fstack-protector-all)이 되어 있어서 diff 리눅스 명령으로 비교를 했으나, 차이점은 없네;
참조)