leetcode (인터뷰 연습)에서 작동하지만 내 시스템에서 놀랍게도 잘못된 액세스 오류가 발생하는 간단한 in-place 문자열 반전 기능을 작성했습니다. 그것은 아주 간단한 기능이며 디버거가 나에게 알리는 모든 것들은 그것이 A-OK 이어야만하는 것처럼 보입니다. 왜 나는 나쁜 접근을하고 있는가?const char * 덮어 쓰기 시도가 잘못되었습니다.
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
char* reverseString(char* s) {
char *t,*r,tmp;
t=r=s;
while(*(s++));
s-=2;
while(t<s){
tmp=*t;
*t=*s; //<--- this is where I have a bad access(?)
*s=tmp;
s--;
t++;
}
return r;
}
int main(){
char *s="12345";
reverseString(s);
return 0;
}
저와 함께 있으시면 디버거 정보가 매우 간단합니다. 심지어 lldb에 *t=*s;
를 호출하고 예상 된 결과를 얻을 수 있습니다
╰─$ lldb ./a.out
lldb ./a.out
(lldb) target create "./a.out"
Current executable set to './a.out' (x86_64).
(lldb) r
r
Process 38750 launched: './a.out' (x86_64)
Process 38750 stopped
* thread #1: tid = 0xa0c378, 0x0000000100000f23 a.out`reverseString(s="5") + 99 at reverse-string.c:12, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x100000f91)
frame #0: 0x0000000100000f23 a.out`reverseString(s="5") + 99 at reverse-string.c:12
9 s-=2;
10 while(t<s){
11 tmp=*t;
-> 12 *t=*s;
13 *s=tmp;
14 s--;
15 t++;
(lldb) frame variable
frame variable
(char *) s = 0x0000000100000f95 "5"
(char *) t = 0x0000000100000f91 "12345"
(char *) r = 0x0000000100000f91 "12345"
(char) tmp = '1'
(lldb) call *s
call *s
(char) $0 = '5'
(lldb) call *t
call *t
(char) $1 = '1'
(lldb) call *t=*s
call *t=*s
(char) $2 = '5'
(lldb)
알 수 있습니다. 뭐라 구요?
알 수 있습니다. 그래서 함수는 괜찮지 만 문자열 상수를 전달해서는 안됩니다. 이것이 테스트 케이스를 적절하게 만드는 leetcode가 오류를 던지지 않는 이유를 설명합니다. 이 일은 내가 할 수 없다면 걱정이되어서 ... – Alejandro