[C언어오류] 예외가 발생함:: 예외가 throw됨: 읽기 액세스 위반입니다.

두비니

·

2020. 4. 4. 13:59

[C언어오류] 예외가 발생함:: 예외가 throw됨: 읽기 액세스 위반입니다.

 

 

 

 

 

 

 

 

 

 

**참고로 예시로 써놓은 선택정렬 코드 자체가 엉망입니다. 혹시라도 선택정렬 자체가 궁금하신분들은 이 코드말고 아래 링크를 참조해주세요**

 

https://dokhakdubini.tistory.com/172

 

[자료구조] 선택정렬(Selection Sort)에 대하여

Data_Structure 선택정렬에 대하여 About. Selection Sort 정의: 1개이상의 서로 다른 정수를 가장 작은순서부터 배열하는 정렬 배열할때 가장 작은 수부터 배열하고싶으면, 가장 작은 숫자를 찾아서 맨 처음, 그..

dokhakdubini.tistory.com

 

 

#include <stdio.h>
#define swap(a, b, tmp){(tmp) = (a); (a) = (b); (b) = (tmp);}

void selec_sort(int *list, int n);

int main() {
	int n, *list;

	printf("배열의 크기는? ");
	scanf(" %d", &n);
	list = malloc(sizeof(int) * n);

	for (int i = 0; i < n; i++) {
		printf("%d번째 숫자를 입력해주세요: ", i + 1);
		scanf("%d", &list[i]);
	}

	selec_sort(*list, n);
}

void selec_sort(int *list, int n) {
	int i, tmp;
	int min = 1;

	for (i = 0; i < n; i++) {
		if (list[min] > list[i]) {
			swap(list[min], list[i], tmp);
            min = i;
		}
	}

	printf("정렬된 배열: ");
	for (i = 0; i < n; i++) {
		printf("%d ", list[i]);
	}
}

 

위와같이 코드를 작성하게되면 컴파일에러는 없지만,

실행하는 도중 맘대로 종료가 되어버립니다.

 

원래는 선택정렬한 결과를 내뱉고 종료가 되어야 합니다.

 

 

 

이게 우째된일인지 디버거로 살펴봅시다.

 

 

 

 

예외가 throw됨: 읽기 액세스 위반입니다.

list이(가) 0x1110113였습니다.

 

 

list를 포인터로 받아온 selec_sort() 함수에서 list[i]를 불러오는데 문제가 있는 것 같네요.

 

 

조사식 값도 확인해보니, 

 

 

 

문제의 list[i]가 메모리를 읽을 수 없다고 하네요.

 

 

이런 에러는 보통 포인터, 즉 주소를 넘겨주어야하는 하는 곳에서 값 자체를 넘겨주어서 그렇습니다.

 

 

void selec_sort(int *list, int n)

 

selec_sort()함수를 보면 int형 포인터와 int형 변수를 받고 있습니다.

 

 

18번줄 보면 제가 바보같이도 주소인 list가 아닌 *list값을 넘겨주어서 에러가 생겼네요.

제가 위에서 작성한대로 코드를 진행해보자면, 

 

크기 5/ [1, 2, 3, 4, 5] 라는 배열이 list에 있다면

배열의 이름은 첫번째 원소의 주소를 뜻하므로

 

 

1. 18번줄에서 selec_sort라는 함수에는 list = 0x1과 n=5 가 넘어가게 됩니다. 

2. 26번에서는 list[min]과 list[i]를 비교하게 되는데, 저렇게되면 주소 0x1의 주변값들을 접근하려고합니다.

3. (당연히)프로그램이 터집니다. 우선 0x1이라는 주소는 존재하지 않을 것이고 존재한다고해도 접근 불가능하겠죠.

 

 

그렇기때문에 말그대로 '읽기' 액세스 위반이 발생합니다.

 

 


!해결법!

 

원인자체가 주소가 아닌 값을 넘겨주어 발생한 오류이니 값이 아닌 주소를 넘겨주면 되겠죠.

 

 

 

	selec_sort(list, n);

코드가 너무 길어서 문제의 18번만 수정한 상태로 가져왔습니다.

 

 

 

 

 

 

::결론::

 

 

1. 내가 주소를 넘겨주어야하는데 값을 넘겨준거일테니 '그곳'을 잘 찾아보자.

2. 그곳은 보통 함수를 호출하는 부분일거니까 그걸 보자.

 

 

 

 

 

 

 

 

참고로 저건 선택정렬에대한 코드 자체가 틀린 엉터리코드죠.

 

코딩을 몇달 쉬었더니...

 

코딩을 몇달 쉬어서 그런거라고...변명하겠습니다....

코드는 무시해주시고 혹시라도 선택정렬에대해 궁금하신 분들은 위에 첨부해놓은 링크를 봐주시길....