Computer_Language/C

[C] 위치를 기록하는 동안 액세스 위반이 발생했습니다. 에 관하여

Joo-Topia 2019. 8. 27. 13:45

C는 내가 처음으로 공부했던 컴퓨터 언어이다.

백준 문제도 많이 풀어보고, 게임을 만들거나 자료구조를 시각화하는 등 다양하게 코딩을 했던 것 같다.

오늘은 처음으로 C에 대해서 깊게 공부하게 되었던 "액세스 위반"에 대해 정리를 해보려고 한다.

비쥬얼 스튜디오의 흔한 에러

1. 어떤 경우에 위반이 떴나?


내가 경험했던 경우는 두 가지이다.

1. 메모리 할당이 되지 않은 포인터를 잘못 사용할 경우.

2. 읽기 전용 메모리에 쓰기를 수행할 경우.

 

1번의 경우는 "할당되지 않은 메모리를 사용하려고 할 때"라고 표현해도 좋을 것 같다.

 

 

2. 직접 액세스 위반을 발생시켜보며 공부하자


먼저 "1. 메모리 할당이 되지 않은 포인터를 잘못 사용할 경우."에 대해 공부해보았다.

예제 1-1)

정상적인 오류가 없는 정상적인 코드이다.

#include <stdio.h>

int main() {
    int *ptr;
    int num = 10;
    
    ptr = &num;
    printf("%d\n", *ptr);
    
    return 0;
}

코드 내에서 어떠한 위반도 발생하지 않았기 때문에 예상했던 출력 그대로 나온다.

 

 

예제 1-2)

다음은 액세스 위반이 발생하는 코드이다.

#include <stdio.h>

int main() {
    int *ptr;
    int a = 10;
    
    ptr[0] = 10;
    printf("%d\n", *ptr);
    
    return 0;
}

실행시켜보면 오류가 발생할 것이다.

디버그를 통해 다음과 같은 오류가 발견할 수 있다.

ptr은 메모리가 할당되지 않은 포인터 변수이고, 할당되지 않은 메모리에 index를 사용하여 접근하려고 하기 때문에 참조 액세스 위반이 발생했다.

머리에 확 들어오지 않아서 그림으로 그려보았다.

포인터 변수는 무언가 가리키는 변수이다. 이미 메모리가 할당된 변수를 할당해주거나, 메모리를 직접 할당하여 사용해야 한다.

위 그림의 첫 번째 경우가 예제 1-1의 경우이다.

예제 1-2의 경우는 아무것도 할당되지 않은 ptr변수에 index 연산자를 사용하여 접근하려고 했기 때문에 참조 위반이 발생한 것이구나!

생각보다 어려운 개념은 아닌 것 같다.

 

다음은 "2. 읽기 전용 메모리에 쓰기를 수행할 경우."에 대해서 공부해보았다.

예제 2-1

 #include <stdio.h>

int main() {
    char str[10] = "apple";
	
    str[0] = 'B';
    printf("%s\n", str);

    return 0;
}

위 코드에서 "apple"은 init영역에 존재하는 문자열 리터럴이고, str은 크기가 10으로 할당된 char형 배열이다.

배열 str은  문자여 리터럴 "apple"로 초기화(copy) 되어 stack영역에 저장되기 때문에 인덱스 연산자로 접근 시 문제가 되지 않는다. (읽고 쓰기가 가능한 데이터 영역이다.)

결과는 당연히 "Bapple"이 출력된다. 따로 사진으로 남겨두지는 않았다.

 

예제 2-2

#include <stdio.h>

int main() {
    char *str = "apple";
	
    str[0] = 'B';
    printf("%s\n", str);
	
    return 0;
}

위 코드를 실행하면 다음과 같은 액세스 위반이 발생한다.

예제 2-1의 배열 str과 다르게 2-2의 str은 포인터 변수이고 init영역에 존재하는 리터럴 타입 문자열 "apple"을 가리키고 있다.

init영역은 읽기 전용 메모리이기 때문에 init영역에 할당되어있는 변수에는 쓰기 명령으로 접근할 수 없다.

이러한 이유 때문에 액세스 위반이 발생했다고 생각한다.

 

마무리


C는 공부하면 공부할수록 어려워지는 언어인 것 같다.

다음번엔 string 헤더 파일과 L, R value 등에 대해 정리해 볼 계획이다.

공부에 사용한 코드는 아래 링크에 주석과 함께 올려두었다.

https://github.com/Sungmin-Joo/Codes-for-Beginners/tree/master/C/Memory_Structure_study

'Computer_Language > C' 카테고리의 다른 글

[C] C언어의 Stack_Frame  (0) 2019.10.15
[C] 인덱스 검사(경계 검사)에 대하여  (0) 2019.08.31