혹시 이 코드 어떤 부분에서 segmentation falut가 떴는지 알려주실 수 있으실까요?
글쓴이: 김태민@Google / 작성시간: 일, 2020/12/06 - 1:30오전
C언어로 split 함수를 구현해봤습니다.
테스트를 돌렸는데 segmentation fault가 발생했습니다.
size_t ft_count_words(const char *s, char c) { size_t i; size_t count; size_t ibool; i = 0; count = 0; ibool = 1; while (s[i]) { while (s[i] == c && s[i]) i++; while (s[i] != c && s[i]) { if (ibool == 1) count++; ibool = 0; i++; } ibool = 1; } return (count); } size_t ft_splitlen(const char *str, char c) { size_t i; i = 0; while (str[i] != c && str[i]) i++; return (i); } char *ft_splitdup(const char *str, char c) { char *word; size_t i; i = 0; if (!(word = (char *)malloc((ft_splitlen(str, c) + 1) * sizeof(char)))) return (NULL); while (str[i] != c && str[i]) { word[i] = str[i]; i++; } word[i] = '\0'; return (word); } char **ft_splitfree(char **base_split) { size_t i; i = 0; while (base_split[i]) { free(base_split[i]); i++; } free(base_split); return (NULL); } char **ft_split(const char *s, char c) { char **best_split; size_t i; size_t j; if (!s || !c) return (NULL); i = 0; j = 0; if (!(best_split = (char **)malloc((ft_count_words(s, c) + 1)\ * sizeof(char *)))) return (NULL); while (s[i]) { while (s[i] == c && s[i]) i++; while (s[i] != c && s[i]) { if (!(best_split[j] = ft_splitdup(s + i, c))) return (ft_splitfree(best_split)); i += ft_splitlen(s + i, c); j++; } } best_split[j] = NULL; return (best_split); } int main() { char **test; test = ft_split("lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse", ' '); }
vingrind를 사용해서 메모리 누수를 체크해봤더니 아래와 같이 메세지가 출력됐습니다.
==348== Memcheck, a memory error detector ==348== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==348== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info ==348== Command: ./test ==348== ==348== ==348== HEAP SUMMARY: ==348== in use at exit: 188 bytes in 13 blocks ==348== total heap usage: 13 allocs, 0 frees, 188 bytes allocated ==348== ==348== 188 (104 direct, 84 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 2 ==348== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==348== by 0x1093D8: ft_split (ft_split.c:91) ==348== by 0x109506: main (ft_split.c:113) ==348== ==348== LEAK SUMMARY: ==348== definitely lost: 104 bytes in 1 blocks ==348== indirectly lost: 84 bytes in 12 blocks ==348== possibly lost: 0 bytes in 0 blocks ==348== still reachable: 0 bytes in 0 blocks ==348== suppressed: 0 bytes in 0 blocks ==348== ==348== For lists of detected and suppressed errors, rerun with: -s ==348== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
아마 메모리를 할당하는 malloc 부분에서 잘못된 메모리를 접근한 것 같은데 저는 도대체 어떤 부분에서 문제가 발생한건지 모르겠습니다.
조언 부탁드립니다
Forums:
dump 파일(없으면 생성되도록 설정해서)을 가지고
dump 파일(없으면 생성되도록 설정해서)을 가지고 gdb로 debug를 해보세요.
아마 아래와 같이 하면 될 겁니다.
gdb 실행파일명 dump파일명
bt
frame 0
자세한 건 google에게 물어보세요.
메모리 leak 은 malloc 으로 할당해 사용하고
메모리 leak 은 malloc 으로 할당해 사용하고 해제를 안하면 발생하잖아요.
위에 코드를 보면 메모리 해제를 ft_splitfree 함수에서 하고 있는데
gdb 에서 break point 를 ft_splitfree 함수에 걸고 실행해보면 한번도 stop 이 되지않아요.
다시말해서 메모리 해제가 전혀 안되고 있다는거죠.
C 잘하려면 코딩하는것 만큼이나 gdb 사용을 잘해야 되요.
음 ..
위 코드 돌려봐도 별 문제는 없어 보이는데요..
memory leak 은 main 에서 종료할 때 char **test 해제 안 해줘서 그런거니, 그거 free 해주면 될 거고..
정말로 segfault 가 떨어졌다면, 실제 문제가 생긴 부분은 다른 데에 있을 겁니다.
그럴 때는 "ulimit -c unlimited" 쳐서 core dump 생성되도록 하고..
실행파일 실행한 후에, segfault 떨어지면 core 파일이 있을 겁니다.
"gdb 실행파일 core" 실행한 후에..
gdb 프롬프트에서 "bt" 라고 치면 어디서 죽었는지 알 수 있을 겁니다.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
댓글 달기