배열과 포인터를 사용하다 보면 에러들이 많이 발생한다.
여러 이유가 있는데,
data가 Read Only영역으로 할당 된 경우 접근하려 하면,
런타임에러(실행하다 프로그램 오류로 종료되는 것)가 발생하며...
또는 constant 타입으로 선언된 배열의 이름에 포인터 값을 전달하는
경우등에서 프로그램 컴파일 오류가 발생하기도 한다.
아래는 다양한 오류에 대해 직접 실행해보고 정리한 내용이다.
11가지 정도인데, 이 정도면 대부분의 상황이 설명될 듯 하다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | // case 1 void main(void) { char *p = "C_PROGRAM"; char str[20] = "C_PROGRAM"; p[0] = 'B'; // [런타임 에러] Read Only 영역에 쓰려하면 에러 // 예외 발생(0x0F4E0E29(ucrtbased.dll), C_TEST_01.exe): // 0xC0000005: 0x01376B30 위치를 기록하는 동안 액세스 위반이 발생했습니다.. // 포인터가 가르키는 "C_PROGRAM" 문자열은 Read Only 메모리 영역에 있는 값이므로, // 이 포인터가 가르키는 곳을 수정하려 하면, Read only 영역 접근 문제가 발생한다... 그러나 // 프로그램은 이것이 실행되기 전까지 빌드 에러등으로 경고하지 못한다. str[0] = 'B'; // 위의 라인이 없다면, 에러 없이 실행됨. printf("Good bye~!\n"); } // case 2 void main(void) { char *p = "C_PROGRAM"; char str[20] = "C_PROGRAM"; str[0] = 'B'; strcpy(p, "JAVA"); // [런타임 에러] Read Only영역에 쓰려하므로 Access 에러 // 예외 발생(0x0F4E0E29(ucrtbased.dll), C_TEST_01.exe): 0xC0000005: 0x01376B30 // 위치를 기록하는 동안 액세스 위반이 발생했습니다.. // 바로 위의 상황과 동일 ... strcpy도 Read Only영역에 다른 값을 쓰는 시도이므로... printf("Good bye~!\n"); } // case 3 void main(void) { char *p = "C_PROGRAM"; char str[20] = "C_PROGRAM"; str[0] = 'B'; printf("str = %s \n", str); strcpy(str, "JAVA"); printf("str = %s \n", str); printf("Good bye~!\n"); } // case 4 void main(void) { char *p = "C_PROGRAM"; char str[20] = "C_PROGRAM"; p = "PYTHON"; str = "PYTHON"; // [컴파일 에러] 오류 : 식이 수정할 수 있는 lvalue여야 합니다. // error C2106: '=': 왼쪽 피연산자는 l-value이어야 합니다. // 배열의 이름은 그배열이 시작하는 주소값이므로, 만약 이것이 바뀌게 되면, 배열의 시작 위치가 // 사라지게 되므로, 이를 수정하기 못하도록 컴파일러가 에러로 막습니다. printf("p = %s \n", p); printf("str = %s \n", str); printf("Good bye~!\n"); } // case 5 void main(void) { char *p = "C_PROGRAM"; char str[20] = "C_PROGRAM"; strcpy(p, "C++"); // [런타임 에러] Read only영역에 다른 값을 쓰려하므로... // 예외 발생(0x0FD20E62(ucrtbased.dll), C_TEST_01.exe): 0xC0000005: 0x00046B30 // 위치를 기록하는 동안 액세스 위반이 발생했습니다.. strcpy(str, "C++"); printf("p = %s \n", p); printf("str = %s \n", str); printf("Good bye~!\n"); } // case 6 void main(void) { char *p = "C_PROGRAM"; char str[20] = "C_PROGRAM"; strcpy(str, "C++"); // 정상 처리됨. printf("p = %s \n", p); printf("str = %s \n", str); printf("Good bye~!\n"); } // case 7 void main(void) { char *p = "C_PROGRAM"; //p값 주소 = 0x002e6b30 에... "C_PROGRAM" 내용이 있음. char str[20] = "C_PROGRAM"; p = "PYTHON"; // 정상 처리됨. "PYTHON"이라는 문자열이 있는 주소를 넣는 것. //p값 주소 = 0x002e6bf0 로... 주소가 바뀜. 그리고 내용도 "PYTHON"으로 내용이 바뀜. printf("p = %s \n", p); printf("str = %s \n", str); printf("Good bye~!\n"); } // case 8 void main(void) { char *p; char str[20] = "C_PROGRAM"; p[0] = "B"; // [런타임 에러] 포인터를 초기화 하지 않고 사용하여, run time error발생, malloc을 하거나, // str의 주소를 넣던지... 해야함. printf("p = %s \n", p); printf("str = %s \n", str); printf("Good bye~!\n"); } // case 9 void main(void) { char *p; char str[20] = "C PROGRAM"; p = str; // str의 주소를 p에 넣는다. p[0] = 'B'; // 배열의 주소를 받았으므로, 배열의 구성 요소 변경은 문제가 없는 것 같다. printf("p = %s \n", p); printf("str = %s \n", str); printf("Good bye~!\n"); } // case 10 void main(void) { char *p; char str[20] = "C PROGRAM"; p = str; // str의 주소를 p에 넣는다. p[0] = 'B'; // 배열의 주소를 받았으므로, 배열의 구성 요소 변경은 문제가 없는 것 같다. str[0] = 'B'; printf("p = %s \n", p); printf("str = %s \n", str); strcpy(p, "JAVA"); strcpy(str, "JAVA"); printf("p = %s \n", p); printf("str = %s \n", str); printf("Good bye~!\n"); } // case 11 void main(void) { char *p; char str[20] = "C_PROGRAM"; p = str; // str의 주소를 p에 넣는다. p[0] = 'B'; // 배열의 주소를 받았으므로, 배열의 구성 요소 변경은 문제가 없는 것 같다. // case 1, 2 번에서는 char *p = "C_PROGRAM" 이라고 선언시 초기화하였고, // 여기서는 초기화 하지 않아 Read only영역이 되지 않았다. str[0] = 'B'; printf("p = %s \n", p); printf("str = %s \n", str); strcpy(p, "JAVA"); strcpy(str, "JAVA"); printf("p = %s \n", p); printf("str = %s \n", str); p = "PYTHON"; // 이 초기화로 p는 Read Only영역을 가리키게됨.. printf("p = %s \n", p); strcpy(p, "JAVA"); // [런타임 에러] Read Only를 access하려 하니 런타임 에러 발생함. // 예외 발생(0x0F130E29(ucrtbased.dll), C_TEST_01.exe): // 0xC0000005: 0x00036C00 위치를 기록하는 동안 액세스 위반이 발생했습니다.. printf("p = %s \n", p); printf("Good bye~!\n"); } | cs |