Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 이지젯
- 지베르니
- 와인 고르기
- str함수
- 에꼴42
- 포르투갈 여행
- printf
- 42 pipex
- 지베르니 가을
- 42 libft
- 지베르니 여름
- so_long
- push swap
- get_next_line
- 지베르니 계절 추천
- pipex
- 42 so_long
- ft_printf
- gnl
- 파리 피크닉
- pipex 42
- get next line
- 와인선별방법
- 굿노트 스티커
- ecole42
- 42
- push swap 설명
- 알고리즘 기초
- 서울42
- libft
Archives
- Today
- Total
뇌 마음 반반저장소
[42] valgrind로 메모리 누수 찾기 본문
728x90
memory leak을 찾는 프로그램 Valgrind를 친구들이 많이 쓰는 것을 보았다. 일단 설치하자.
$ sudo apt-get install valgrind
설치 후 프로그램을 실행할 때 앞에 valgrind 만 붙여주면 된다. 일부러 free를 하지 않고 코드 하나를 만들어 봤다.
#include <stdio.h>
#include <stdlib.h>
void main()
{
char *str;
str = malloc(sizeof(char) * 10);
str = "Valgrind test!";
printf("%s\n", str);
}
free가 없는 malloc 함수를 하나 만들었다.
$ gcc valgrind_test.c
$ ./a.out
Valgrind test!
실행은 잘 되지만 valgrind를 사용해서 프로그램을 돌려보면,
$ valgrind ./a.out
==3729== Memcheck, a memory error detector
==3729== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3729== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==3729== Command: ./a.out
==3729==
Valgrind test!
==3729==
==3729== HEAP SUMMARY:
==3729== in use at exit: 10 bytes in 1 blocks
==3729== total heap usage: 2 allocs, 1 frees, 1,034 bytes allocated #2개 빌렸는데 1개만 free되었다.
==3729==
==3729== LEAK SUMMARY:
==3729== definitely lost: 10 bytes in 1 blocks #이곳을 잘 보자
==3729== indirectly lost: 0 bytes in 0 blocks
==3729== possibly lost: 0 bytes in 0 blocks
==3729== still reachable: 0 bytes in 0 blocks
==3729== suppressed: 0 bytes in 0 blocks
==3729== Rerun with --leak-check=full to see details of leaked memory #더 자세한 메모리 누수를 확인할 수 있다.
==3729==
==3729== For lists of detected and suppressed errors, rerun with: -s
==3729== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
이렇게 길게 나온다는 것은 뭔가 문제가 있다는 소리다. 위의 설명을 보면 1개가 해제가 안된 것을 볼 수 있다.
아래의 명령어를 추가하면 어디서 누수가 되었는지 자세한 함수를 설명해 준다.
$ valgrind --leak-check=full ./a.out
==3740== Memcheck, a memory error detector
==3740== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3740== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==3740== Command: ./a.out
==3740==
Valgrind test!
==3740==
==3740== HEAP SUMMARY:
==3740== in use at exit: 10 bytes in 1 blocks
==3740== total heap usage: 2 allocs, 1 frees, 1,034 bytes allocated
==3740==
==3740== 10 bytes in 1 blocks are definitely lost in loss record 1 of 1
==3740== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==3740== by 0x10917E: main (in /mnt/c/Users/.../a.out) #요 함수들에서 안된걸 확인할 수 있다.
==3740==
==3740== LEAK SUMMARY:
==3740== definitely lost: 10 bytes in 1 blocks
==3740== indirectly lost: 0 bytes in 0 blocks
==3740== possibly lost: 0 bytes in 0 blocks
==3740== still reachable: 0 bytes in 0 blocks
==3740== suppressed: 0 bytes in 0 blocks
==3740==
==3740== For lists of detected and suppressed errors, rerun with: -s
==3740== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
free를 추가해서 메모리를 모두 해제해 보자.
$ valgrind ./a.out
==3859== Memcheck, a memory error detector
==3859== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3859== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==3859== Command: ./a.out
==3859==
Valgrind test!
==3859== Invalid free() / delete / delete[] / realloc()
==3859== at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==3859== by 0x1091C5: main (in /mnt/c/Users/MJi/Desktop/Ecole/복습/a.out)
==3859== Address 0x10a004 is in a r-- mapped file /mnt/c/Users/MJi/Desktop/Ecole/복습/a.out segment
==3859==
==3859==
==3859== HEAP SUMMARY:
==3859== in use at exit: 100 bytes in 1 blocks
==3859== total heap usage: 2 allocs, 2 frees, 1,124 bytes allocated #잘 해제가 되었다.
==3859==
==3859== LEAK SUMMARY:
==3859== definitely lost: 100 bytes in 1 blocks #홋? 이건 무슨 뜻일까?
==3859== indirectly lost: 0 bytes in 0 blocks
==3859== possibly lost: 0 bytes in 0 blocks
==3859== still reachable: 0 bytes in 0 blocks
==3859== suppressed: 0 bytes in 0 blocks
==3859== Rerun with --leak-check=full to see details of leaked memory
==3859==
==3859== For lists of detected and suppressed errors, rerun with: -s
==3859== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
LEAK SUMMARY에 아직 문제가 있는 부분이 있다. 위의 다섯 가지 카테고리가 뭔지 확인해 보자.
definitely lost / 확실히 손실됨 : 확실히 손실된 첫 번째 범주는 해당 메모리를 사용하거나 복구할 방법이 없기 때문에 일반적으로 추적해야 할 가장 시급한 누출 유형이다.
indirectly lost / 간접적으로 손실됨 : 주소 포인터를 잃어버린 경우
possibly lost / 손실 가능성 : 주소 포인터가 해제되지 않고 남아있는 경우
still reachable / 여전히 도달 가능: 종료 직전까지 메모리를 차지하는 경우
suppressed / 억제됨 : 라이브러리 혹은 외부 프로세스 간에 메로리를 공유하는 과정에서의 누수
그래서 str에 직접 문자열을 넣지 않고 메모리에 문자열을 복사해주는 함수인 memcpy를 사용하니 해결되었다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *str;
str = malloc(sizeof(char) * 100);
memcpy(str, "Valgrind test!", strlen(str));
printf("%s\n", str);
free(str);
return(0);
}
$ valgrind ./a.out
==4032== Memcheck, a memory error detector
==4032== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==4032== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==4032== Command: ./a.out
==4032==
==4032== Invalid read of size 1
==4032== at 0x483EF54: strlen (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4032== by 0x48E0433: puts (ioputs.c:35)
==4032== by 0x1091E6: main (in /mnt/c/Users/MJi/Desktop/Ecole/복습/a.out)
==4032== Address 0x4a5104e is 0 bytes after a block of size 14 alloc'd
==4032== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4032== by 0x1091BE: main (in /mnt/c/Users/MJi/Desktop/Ecole/복습/a.out)
==4032==
Valgrind test!
==4032==
==4032== HEAP SUMMARY:
==4032== in use at exit: 0 bytes in 0 blocks
==4032== total heap usage: 2 allocs, 2 frees, 1,038 bytes allocated
==4032==
==4032== All heap blocks were freed -- no leaks are possible
==4032==
==4032== For lists of detected and suppressed errors, rerun with: -s
==4032== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
728x90
'좌뇌 > 왕초보의 컴퓨터 언어 세계' 카테고리의 다른 글
왕초보의 알고리즘 정렬 종류 파헤치기 1 (자료구조, 시간 공간 복잡도) (0) | 2023.01.19 |
---|---|
자료구조 (Data Structure) 기본 이해하기 (0) | 2023.01.18 |
[42] const char의 *위치에 따른 다른 의미 (0) | 2023.01.05 |
[42]void 함수인데 return 값이 가능하다구? (0) | 2022.12.29 |
[42] argc, argv 거 어떻게 쓰는 겁니까? (0) | 2022.12.04 |
Comments