본문 바로가기

C++ and STL

segmentation fault를 조심하자

C++ STL의 컨테이너를 다룰 때 정상적으로 컴파일은 되었으나, 실행단계에서 segmentation fault를 발생시키는 경우가 종종 발생한다. segmentation fault는 주로 할당되지 않은 메모리 공간에 접근할 때 발생한다. 아래 예제에서는 크기 10의 배열을 만들고 각 배열에 값을 할당하고 있다.

 

#include <iostream>
#include <array>
#include <algorithm>

using namespace std;

array<int, 10> arr;

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	int T, elm=10;
	cin >> T;
	while (T--)
	{
		while (elm--)	
		{
			cin >> arr[i]; 
		}			
		sort(arr.begin(), arr.end());
		cout << arr[7] << '\n';
	}
	return 0;
}

 

그냥 봐서는 문제가 없어 보이나 위 예제는 segmentation fault를 발생시킨다. 배열의 크기가 10이므로 인덱스는 0에서 9까지만 갖게될 것이다. 그런데 17행의 while (elm--) 구문에서 인덱스 10에 접근하려고 했기 때문이다. 이 경우 그냥 for 문으로 인덱스 0에서 9까지 순회하며 값을 할당하면 된다.

 

#include <iostream>
#include <array>
#include <algorithm>

using namespace std;

array<int, 10> arr;

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	int T, elm=10;
	cin >> T;
	while (T--)
	{
		for (int i = 0; i < elm; i++)	
		{
			cin >> arr[i]; 
		}			
		sort(arr.begin(), arr.end());
		cout << arr[7] << '\n';
	}
	return 0;
}

 

다음으로 살펴볼 예제는 컨테이너의 사이즈를 초기화 하지 않은 상태에서 인덱스에 접근하는 경우다. 예제에서는 x, y좌표를 입력받아 x의 오름차순으로 같으면 y의 오름차순으로 정렬한다. 7행에서 벡터 coords의 사이즈를 정의하지 않은 상태로 생성했다. 그런데 20행에서 coords[i] = p; 로 vector에 값을 할당하고 있다.

 

#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>

using namespace std;
vector<pair<int, int>> coords;

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	int N, x, y;
	cin >> N;

	for (int i = 0; i < N; i++)
	{
		cin >> x >> y;
		pair<int, int> p = make_pair(x, y);
		coords[i] = p;
	}
	sort(coords.begin(), coords.end());

	for (int i = 0; i < N; i++)
		cout << coords[i].first << ' ' << coords[i].second << '\n';
 	return 0;
}

 

이 경우는 coords 벡터의 인덱스를 확인할 수 없으므로 segmentation fault가 발생한다. 아래와 같이 push_back() 메서드로 값을 추가하자.

 

#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>

using namespace std;
vector<pair<int, int>> coords;

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	int N, x, y;
	cin >> N;

	for (int i = 0; i < N; i++)
	{
		cin >> x >> y;
		pair<int, int> p = make_pair(x, y);
		coords.push_back(p);
	}
	sort(coords.begin(), coords.end());

	for (int i = 0; i < N; i++)
		cout << coords[i].first << ' ' coords[i].second << '\n';
   	return 0;
}

 

segmentation fault는 찾기가 쉽지 않다. 항상 컨테이너를 사용할 때는 인덱스의 시작값과 끝값이 무엇인지 염두에 두고 그 값의 범위를 넘어서는 접근을 시도하지 않는지 점검할 필요가 있다.

'C++ and STL' 카테고리의 다른 글

[STL] 컨테이너 정렬상태 확인 is_sorted()  (0) 2022.03.06
[C++] endl을 쓰지말자  (0) 2022.03.01