Valgrid Memory Problem Checking under linux

Keywords: C++ Linux socket

_c/c++ memory management has always been the most headache for programmers. Memory crossing, array crossing, memory leak, memory overflow, wild pointer, empty pointer, any problem may cause program crash. And often the source of the problem is relatively hidden, making it difficult to find out the root cause of the problem.
If we want to solve this problem, we must start from the root of the problem. Valgrid is a powerful memory management tool, which is often used to detect memory leaks and illegal use of memory. If used well, it can solve the problem of c/c++ memory management from the root.

1. Main functions of valgrid

_virgrid can be used to detect the vast majority of memory in program development. Functions, cache usage, multi-threaded competitive access to memory, stack problems, is a powerful memory detection tool under linux.

1 valgrid tool

_valgrind-tool=<name> is the most commonly used option. Run the tool named toolname in valgrid. Default memcheck.

_memcheck: This is the most widely used tool for valgrid. A heavyweight memory checker can detect most memory errors in development, such as using uninitialized memory, using freed memory, memory access crossing the bounds, etc. This feature will be highlighted below.

_callgrind: Mainly used to check the problems in the process of function calls in programs.

cachegrind: Mainly used to check for problems with cache usage in programs.

_helgrind: Mainly used to check for competition problems in multithreaded programs.

Masif: Mainly used to check for problems in stack usage in programs.

extension: You can use the functions provided by core to write your own specific memory debugging tools.

2 valgrind memcheck

2.1 MemCheck memory detection principle

_valid-value table:
For every byte in the whole address space of the process, there are 8 bits corresponding to it, and for every register of the CPU, there is also a bit vector corresponding to it. These bits are responsible for recording whether the byte or register values have valid, initialized values.
_valid-Address table:
_For a byte in the whole address space of a process, there is also a bit corresponding to it, which is responsible for recording whether the address can be read or written.
Memory Detection Principle:
When reading or writing a byte in memory, first check the address bit corresponding to that byte. If the address bit indicates that the location is invalid, memcheck reports memory read-write errors. The valgrid kernel is equivalent to a virtual CPU environment. When a byte in memory is loaded into a real CPU, the corresponding value bits of that byte are also loaded into the virtual CPU environment. Once the value in the register is used to generate the memory address, or the value can affect the output of the program, mencheck checks the corresponding value bits. If the value has not been initialized, An uninitialized memory error is reported.

2.2 memcheck memory detection

2.2.1 Prepare source code

Create the source file of gdbmem.cpp and prepare the code to be detected as follows:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <malloc.h>
#include<pthread.h>
#include<string.h>

//memory access overflow
char* stringcopy(char* psrc)
{
    int len = strlen(psrc) + 1;
    char* pdst = (char*)malloc(len);//12
    memset(pdst, 0, len * 2);//13
    memcpy(pdst, psrc, len*2);//14
    return pdst;
}

//array assess overflow
void printarray(int arry[], int arrysize)
{
    int i = 0;
    for(; i < arrysize; i++)
    //for(i = arrysize-1; i >= 0; i--)
    {
        printf("arry[%d]:%d\n",i, arry[i]);
    }
    printf("arry[%d]:%d\n",i+1, arry[i+1]);//27
}

//main body
int main(int narg, const char** args)
{
    char* pwildptr;
    char* pstr = "this is a memory debug program!\n";
    int array[10] = {1,2,3,4,5,6,7,8,9,10};
    char* ptmp = stringcopy(pstr);//36
    //memory leak
    char* ptmp2 = (char*)malloc(100);//38
    memset(ptmp2, 0, 100);
    // memory write overflow
    printf(ptmp);//41
    // array tip assess overflow
    printarray(array, 10);//43
    free(ptmp);//44
    printf("%p", pwildptr);//45
    //wild ptr copy
    memcpy(ptmp, ptmp2, 20);//47
    printf(ptmp);//48
    return 0;
}

2.2.2 Compile source code:

$g++-g-O0-c gdbmem.cpp#-g: Compile obj files with debugging information, -O0: Not optimized
$g++ -o gdbmem gdbmem.o
After compilation, the gdbmem executable file will be generated in the current directory.

2.2.3 valgrid memory detection

_valgring for memory detection of gdbmem

$ valgrind --tool=memcheck --leak-check=full --track-fds=yes ./gdbmem
==10668== Memcheck, a memory error detector
==10668== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==10668== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==10668== Command: ./gdbmem
==10668== 
==10668== Invalid write of size 8
==10668==    at 0x4C3453F: memset (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x40075D: stringcopy(char*) (gdbmem.cpp:13)
==10668==    by 0x40087A: main (gdbmem.cpp:36)
==10668==  Address 0x5204060 is 32 bytes inside a block of size 33 alloc'd
==10668==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x400740: stringcopy(char*) (gdbmem.cpp:12)
==10668==    by 0x40087A: main (gdbmem.cpp:36)
==10668== 
==10668== Invalid write of size 1
==10668==    at 0x4C34558: memset (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x40075D: stringcopy(char*) (gdbmem.cpp:13)
==10668==    by 0x40087A: main (gdbmem.cpp:36)
==10668==  Address 0x5204080 is 16 bytes after a block of size 48 in arena "client"
==10668== 
==10668== Invalid write of size 8
==10668==    at 0x4C326CB: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x400778: stringcopy(char*) (gdbmem.cpp:14)
==10668==    by 0x40087A: main (gdbmem.cpp:36)
==10668==  Address 0x5204060 is 32 bytes inside a block of size 33 alloc'd
==10668==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x400740: stringcopy(char*) (gdbmem.cpp:12)
==10668==    by 0x40087A: main (gdbmem.cpp:36)
==10668== 
==10668== Invalid write of size 2
==10668==    at 0x4C32723: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x400778: stringcopy(char*) (gdbmem.cpp:14)
==10668==    by 0x40087A: main (gdbmem.cpp:36)
==10668==  Address 0x5204080 is 16 bytes after a block of size 48 in arena "client"
==10668== 
this is a memory debug program!
arry[0]:1
arry[1]:2
arry[2]:3
arry[3]:4
arry[4]:5
arry[5]:6
arry[6]:7
arry[7]:8
arry[8]:9
arry[9]:10
arry[11]:-623874025
==10668== Conditional jump or move depends on uninitialised value(s)
==10668==    at 0x4E8890E: vfprintf (vfprintf.c:1631)
==10668==    by 0x4E8F898: printf (printf.c:33)
==10668==    by 0x4008E6: main (gdbmem.cpp:45)
==10668== 
==10668== Use of uninitialised value of size 8
==10668==    at 0x4E84711: _itoa_word (_itoa.c:180)
==10668==    by 0x4E8812C: vfprintf (vfprintf.c:1631)
==10668==    by 0x4E8F898: printf (printf.c:33)
==10668==    by 0x4008E6: main (gdbmem.cpp:45)
==10668== 
==10668== Conditional jump or move depends on uninitialised value(s)
==10668==    at 0x4E84718: _itoa_word (_itoa.c:180)
==10668==    by 0x4E8812C: vfprintf (vfprintf.c:1631)
==10668==    by 0x4E8F898: printf (printf.c:33)
==10668==    by 0x4008E6: main (gdbmem.cpp:45)
==10668== 
==10668== Conditional jump or move depends on uninitialised value(s)
==10668==    at 0x4E881AF: vfprintf (vfprintf.c:1631)
==10668==    by 0x4E8F898: printf (printf.c:33)
==10668==    by 0x4008E6: main (gdbmem.cpp:45)
==10668== 
==10668== Conditional jump or move depends on uninitialised value(s)
==10668==    at 0x4E87C59: vfprintf (vfprintf.c:1631)
==10668==    by 0x4E8F898: printf (printf.c:33)
==10668==    by 0x4008E6: main (gdbmem.cpp:45)
==10668== 
==10668== Conditional jump or move depends on uninitialised value(s)
==10668==    at 0x4E87CE2: vfprintf (vfprintf.c:1631)
==10668==    by 0x4E8F898: printf (printf.c:33)
==10668==    by 0x4008E6: main (gdbmem.cpp:45)

_main function 45 lines, memcpy(ptmp, ptmp2, 20); read the memory that has been released, resulting in memcheck error.

==10668== Invalid write of size 8
==10668==    at 0x4C326CB: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x4008FE: main (gdbmem.cpp:47)
==10668==  Address 0x5204040 is 0 bytes inside a block of size 33 free'd
==10668==    at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x4008D0: main (gdbmem.cpp:44)
==10668==  Block was alloc'd at
==10668==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x400740: stringcopy(char*) (gdbmem.cpp:12)
==10668==    by 0x40087A: main (gdbmem.cpp:36)
==10668== 
==10668== Invalid write of size 2
==10668==    at 0x4C32723: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x4008FE: main (gdbmem.cpp:47)
==10668==  Address 0x5204050 is 16 bytes inside a block of size 33 free'd
==10668==    at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x4008D0: main (gdbmem.cpp:44)
==10668==  Block was alloc'd at
==10668==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x400740: stringcopy(char*) (gdbmem.cpp:12)
==10668==    by 0x40087A: main (gdbmem.cpp:36)
==10668== 
==10668== Invalid read of size 1
==10668==    at 0x4ED0760: strchrnul (strchr.S:24)
==10668==    by 0x4E87207: __find_specmb (printf-parse.h:108)
==10668==    by 0x4E87207: vfprintf (vfprintf.c:1312)
==10668==    by 0x4E8F898: printf (printf.c:33)
==10668==    by 0x40090F: main (gdbmem.cpp:48)
==10668==  Address 0x5204040 is 0 bytes inside a block of size 33 free'd
==10668==    at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x4008D0: main (gdbmem.cpp:44)
==10668==  Block was alloc'd at
==10668==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x400740: stringcopy(char*) (gdbmem.cpp:12)
==10668==    by 0x40087A: main (gdbmem.cpp:36)
==10668== 
==10668== Invalid read of size 1
==10668==    at 0x4E8741A: vfprintf (vfprintf.c:1324)
==10668==    by 0x4E8F898: printf (printf.c:33)
==10668==    by 0x40090F: main (gdbmem.cpp:48)
==10668==  Address 0x5204040 is 0 bytes inside a block of size 33 free'd
==10668==    at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x4008D0: main (gdbmem.cpp:44)
==10668==  Block was alloc'd at
==10668==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x400740: stringcopy(char*) (gdbmem.cpp:12)
==10668==    by 0x40087A: main (gdbmem.cpp:36)
==10668== 
0x40097d==10668== 
==10668== FILE DESCRIPTORS: 3 open at exit.
==10668== Open file descriptor 2: /dev/pts/4
==10668==    <inherited from parent>
==10668== 
==10668== Open file descriptor 1: /dev/pts/4
==10668==    <inherited from parent>
==10668== 
==10668== Open file descriptor 0: /dev/pts/4
==10668==    <inherited from parent>
==10668== 
==10668== 
==10668== HEAP SUMMARY:
==10668==     in use at exit: 100 bytes in 1 blocks
==10668==   total heap usage: 3 allocs, 2 frees, 1,157 bytes allocated
==10668== 
==10668== 100 bytes in 1 blocks are definitely lost in loss record 1 of 1
==10668==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x400888: main (gdbmem.cpp:38)
==10668== 
==10668== LEAK SUMMARY:
==10668==    definitely lost: 100 bytes in 1 blocks
==10668==    indirectly lost: 0 bytes in 0 blocks
==10668==      possibly lost: 0 bytes in 0 blocks
==10668==    still reachable: 0 bytes in 0 blocks
==10668==         suppressed: 0 bytes in 0 blocks
==10668== 
==10668== For counts of detected and suppressed errors, rerun with: -v
==10668== Use --track-origins=yes to see where uninitialised values come from
==10668== ERROR SUMMARY: 37 errors from 15 contexts (suppressed: 0 from 0)

2.2.3 memcheck test results analysis

The LEAK SUMMARY output of memcheck classifies memory leaks into the following situations:
definitely lost: Clearly leaked, because when the program runs out, there is no pointer pointing to it, and the pointer pointing to it is lost in the program.
indirectly lost: indirectly lost. This error may be reported when a class or structure with pointer members is used. Such errors do not need to be repaired directly, they always appear together with "definitely lost", as long as "definitely lost" is repaired.
_possibly lost: A pointer was found to point to the middle of a block of memory, not to the head of the block. This pointer usually points to the head of the memory block, and then moves to the middle of the memory block. It is also possible that the pointer has nothing to do with the memory at all. The detection tool only suspects that there is a memory leak.
_still reachable: accessible, not lost but not released
suppressed: Solved. There was a memory leak but the system handled it automatically. Such mistakes can be ignored.
Memory leak overview:

==10668== LEAK SUMMARY:
==10668==    definitely lost: 100 bytes in 1 blocks
==10668==    indirectly lost: 0 bytes in 0 blocks
==10668==      possibly lost: 0 bytes in 0 blocks
==10668==    still reachable: 0 bytes in 0 blocks
==10668==         suppressed: 0 bytes in 0 blocks

There are only 100 bytes of memory leaks.

==10668== Invalid write of size 8
==10668==    at 0x4C3453F: memset (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x40075D: stringcopy(char*) (gdbmem.cpp:13)
==10668==    by 0x40087A: main (gdbmem.cpp:36)
==10668==  Address 0x5204060 is 32 bytes inside a block of size 33 alloc'd

_According to the error prompt, the string copy function has 13 lines, i.e. memset (pdst, 0, len 2). When applying for len's data length, memset uses 2 len's data length and overwrites memory.

    ==10668==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x400740: stringcopy(char*) (gdbmem.cpp:12)
==10668==    by 0x40087A: main (gdbmem.cpp:36)
==10668== 
==10668== Invalid write of size 1
==10668==    at 0x4C34558: memset (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x40075D: stringcopy(char*) (gdbmem.cpp:13)
==10668==    by 0x40087A: main (gdbmem.cpp:36)
==10668==  Address 0x5204080 is 16 bytes after a block of size 48 in arena "client"

_stringcopy function 13 lines, namely memset(pdst, 0, len2); applied for len's data length, but when memset used 2len's data length, memory overflow. The memory overflow of the same sentence, but reported two errors, the reason I have not yet understood, if there is a shrimp pointing, I would be grateful.

==10668== 
==10668== Invalid write of size 8
==10668==    at 0x4C326CB: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x400778: stringcopy(char*) (gdbmem.cpp:14)
==10668==    by 0x40087A: main (gdbmem.cpp:36)
==10668==  Address 0x5204060 is 32 bytes inside a block of size 33 alloc'd
==10668==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x400740: stringcopy(char*) (gdbmem.cpp:12)
==10668==    by 0x40087A: main (gdbmem.cpp:36)
==10668== 
==10668== Invalid write of size 2
==10668==    at 0x4C32723: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x400778: stringcopy(char*) (gdbmem.cpp:14)
==10668==    by 0x40087A: main (gdbmem.cpp:36)
==10668==  Address 0x5204080 is 16 bytes after a block of size 48 in arena "client"

_stringcopy function 13 lines, namely memcpy(pdst, psrc, len2); applied for len's data length, but when memset used 2 len's data length, memory overflow.

==10668== 
this is a memory debug program!
arry[0]:1
arry[1]:2
arry[2]:3
arry[3]:4
arry[4]:5
arry[5]:6
arry[6]:7
arry[7]:8
arry[8]:9
arry[9]:10
arry[11]:-623874025
==10668== Conditional jump or move depends on uninitialised value(s)
==10668==    at 0x4E8890E: vfprintf (vfprintf.c:1631)
==10668==    by 0x4E8F898: printf (printf.c:33)
==10668==    by 0x4008E6: main (gdbmem.cpp:45)
==10668== 
==10668== Use of uninitialised value of size 8
==10668==    at 0x4E84711: _itoa_word (_itoa.c:180)
==10668==    by 0x4E8812C: vfprintf (vfprintf.c:1631)
==10668==    by 0x4E8F898: printf (printf.c:33)
==10668==    by 0x4008E6: main (gdbmem.cpp:45)
==10668== 
==10668== Conditional jump or move depends on uninitialised value(s)
==10668==    at 0x4E84718: _itoa_word (_itoa.c:180)
==10668==    by 0x4E8812C: vfprintf (vfprintf.c:1631)
==10668==    by 0x4E8F898: printf (printf.c:33)
==10668==    by 0x4008E6: main (gdbmem.cpp:45)
==10668== 
==10668== Conditional jump or move depends on uninitialised value(s)
==10668==    at 0x4E881AF: vfprintf (vfprintf.c:1631)
==10668==    by 0x4E8F898: printf (printf.c:33)
==10668==    by 0x4008E6: main (gdbmem.cpp:45)
==10668== 
==10668== Conditional jump or move depends on uninitialised value(s)
==10668==    at 0x4E87C59: vfprintf (vfprintf.c:1631)
==10668==    by 0x4E8F898: printf (printf.c:33)
==10668==    by 0x4008E6: main (gdbmem.cpp:45)
==10668== 
==10668== Conditional jump or move depends on uninitialised value(s)
==10668==    at 0x4E87CE2: vfprintf (vfprintf.c:1631)
==10668==    by 0x4E8F898: printf (printf.c:33)
==10668==    by 0x4008E6: main (gdbmem.cpp:45)

_main function 45 lines, printf("%p", pwildptr); read the uninitialized field pointer

==10668== 
==10668== Invalid write of size 8
==10668==    at 0x4C326CB: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x4008FE: main (gdbmem.cpp:47)
==10668==  Address 0x5204040 is 0 bytes inside a block of size 33 free'd
==10668==    at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x4008D0: main (gdbmem.cpp:44)
==10668==  Block was alloc'd at
==10668==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x400740: stringcopy(char*) (gdbmem.cpp:12)
==10668==    by 0x40087A: main (gdbmem.cpp:36)
==10668== 
==10668== Invalid write of size 2
==10668==    at 0x4C32723: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x4008FE: main (gdbmem.cpp:47)
==10668==  Address 0x5204050 is 16 bytes inside a block of size 33 free'd
==10668==    at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x4008D0: main (gdbmem.cpp:44)
==10668==  Block was alloc'd at
==10668==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x400740: stringcopy(char*) (gdbmem.cpp:12)
==10668==    by 0x40087A: main (gdbmem.cpp:36)

_main function 47 lines, memcpy(ptmp, ptmp2, 20); write to freed memory

==10668== 
==10668== Invalid read of size 1
==10668==    at 0x4ED0760: strchrnul (strchr.S:24)
==10668==    by 0x4E87207: __find_specmb (printf-parse.h:108)
==10668==    by 0x4E87207: vfprintf (vfprintf.c:1312)
==10668==    by 0x4E8F898: printf (printf.c:33)
==10668==    by 0x40090F: main (gdbmem.cpp:48)
==10668==  Address 0x5204040 is 0 bytes inside a block of size 33 free'd
==10668==    at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x4008D0: main (gdbmem.cpp:44)
==10668==  Block was alloc'd at
==10668==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x400740: stringcopy(char*) (gdbmem.cpp:12)
==10668==    by 0x40087A: main (gdbmem.cpp:36)
==10668== 
==10668== Invalid read of size 1
==10668==    at 0x4E8741A: vfprintf (vfprintf.c:1324)
==10668==    by 0x4E8F898: printf (printf.c:33)
==10668==    by 0x40090F: main (gdbmem.cpp:48)
==10668==  Address 0x5204040 is 0 bytes inside a block of size 33 free'd
==10668==    at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x4008D0: main (gdbmem.cpp:44)
==10668==  Block was alloc'd at
==10668==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x400740: stringcopy(char*) (gdbmem.cpp:12)
==10668==    by 0x40087A: main (gdbmem.cpp:36)

_main function 47 lines, printf(ptmp); write to freed memory

0x40097d==10668== 
==10668== FILE DESCRIPTORS: 3 open at exit.
==10668== Open file descriptor 2: /dev/pts/4
==10668==    <inherited from parent>
==10668== 
==10668== Open file descriptor 1: /dev/pts/4
==10668==    <inherited from parent>
==10668== 
==10668== Open file descriptor 0: /dev/pts/4
==10668==    <inherited from parent>

In order to realize the design philosophy that everything is file, linux abstracts not only data into files, but also all operations and resources into files, such as hardware devices, socket s, disks, processes, threads, etc.
This design unifies all the actions of the system, realizes the atomized operation of the system, and greatly reduces the difficulty of maintenance and operation.
Device descriptor is the only symbol describing the file data device. Different types of files have different file descriptors, as follows:

==10668== 
==10668== 
==10668== HEAP SUMMARY:
==10668==     in use at exit: 100 bytes in 1 blocks
==10668==   total heap usage: 3 allocs, 2 frees, 1,157 bytes allocated
==10668== 
==10668== 100 bytes in 1 blocks are definitely lost in loss record 1 of 1
==10668==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10668==    by 0x400888: main (gdbmem.cpp:38)
==10668== 

Overview of memory leaks, three memory allocations and two releases. Already 100 bytes of memory have been leaked. The leaked memory is allocated to 38 rows, char ptmp2 = char malloc (100); so far, the memory leak detection has been completed.

Valgrid Memory Detection and Resolution

_valgrid can detect memory read-write overflow, read uninitialized variables, pointers and memory well, but it can not detect array crossover, because memcheck does not check stack and global array crossover, so it can not detect memory access crossover in printary.

Posted by nariman on Wed, 15 May 2019 07:47:59 -0700