배열과 포인터를 사용하다 보면 에러들이 많이 발생한다.


여러 이유가 있는데, 


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 *= "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 *= "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 *= "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 *= "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 *= "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 *= "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 *= "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


Posted by 고무함지
,