문제
두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.
입력
첫째 줄에 테스트 케이스의 개수 T가 주어진다.
각 테스트 케이스는 한 줄로 이루어져 있으며, 각 줄에 A와 B가 주어진다. (0 < A, B < 10)
출력
각 테스트 케이스마다 A+B를 출력한다.
풀이 및 코드
해당 문제는 케이스의 개수 T를 입력받는게 주 관건이다. 문제에서 케이스의 개수를 정확히 정해주지 않았기 때문이다.
그래서 배열을 사용하여, T가지의 경우의 수를 받아 들이려고 할 때, 케이스의 개수를 잘 정해주지 않으면 런타임 에러 중 OutOfBounds가 발생한다.
런타임 에러란?
프로그램이 비정상적으로 종료된 경우입니다.
그리고 OutOfBounds는
이렇게, 컨테이너 또는 배열에서 할당된 경계를 넘어가는 접근이 발생할 경우에 일어난다고 설명이 되어 있다.
예시 1을 보면, 케이스의 수가 정해지지 않아서 임의의 수 20으로 선언하였다.
해당 경우는 백준에서 원하는 조건에 비해, 범위가 너무 좁기 때문에 런타임에러가 발생한다.
그러면, 배열의 크기를 엄청 크게 하면 될까?
지역 변수, 배열은 데이터가 메모리의 스택(stack)영역에 저장이 된다. 그래서, 메모리의 용량이 상당히 작기 때문에 메모리의 크기를 크게 잡게 될 경우, 메모리 초과로 오류가 발생하게 된다.
해결 방법은 배열을 전역 변수로 main()밖에 쓰거나 malloc를 활용하여 동적 메모리 할당을 해주게 되면 메모리 공간이 큰 heap영역에 할당하는 방법이 있다. 그렇지만, 큰 메모리 heap을 사용하기 위해 변수를 전역변수로 사용하는 것은 프로그램의 보안 상 좋지 않을 수 있기 때문에, 추천하지 않는다.
#include<stdio.h>
int main(void)
{
int t = 0, i = 0, ab[100000][2] = { 0 };
scanf("%d", &t);
for (i = 0; i < t; i++) {
scanf("%d %d", &ab[i][0], &ab[i][1]);
}
for (i = 0; i < t; i++) {
printf("%d\n", ab[i][0] + ab[i][1]);
}
return 0;
}
이렇게 배열의 크기를 적당하게 잡아주면, 에러가 발생하지 않고 정답처리가 된다.
지역변수 배열이 할당 가능한 메모리 영역 크기는 리눅스 명령어를 통해 알 수 있다.