返回 char * 时内存泄漏

Memory Leak when returning char *

我正在尝试将 const char * 转换为 set 然后 return 它,它也给了我正确的输出。但是 valgrind 说它有内存泄漏。我在 arch linux 使用 gcc 版本 11.1.0 (GCC) x64_86.

这是我的代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define true 0
#define false 1

char *to_set(const char *a); // fix missing prototype
char *to_set(const char *a)
{
    if (a)
    {
        size_t len = strlen(a);
        size_t cnt = 0, map_append = 0, o = 0;
        int check = false;
        char *set_char = (char *)malloc((sizeof(char) * len) + 1);
        strcpy(set_char, "[=10=]");
        for (cnt = 0; cnt < len; cnt++)
        {
            check = false;
            for (o = 0; set_char[o] != '[=10=]'; o++)
            {
                if (set_char[o] == a[cnt])
                {
                    check = true;
                    break;
                }
            }
            if (check == false)
            {
                set_char[map_append] = a[cnt];
                map_append++;
            }
        }
        return set_char;
    }
    return (char *)NULL; // else case
}

int main(int argc, char const *argv[])
{
    if (argv[1] != NULL)
    {
        char *buff = to_set(argv[1]);
        printf("'%s'\n", buff);
    }
    else
        printf("no input\n");
    return 0;
}

Valgrind 错误消息:

==19499== Memcheck, a memory error detector
==19499== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==19499== Using Valgrind-3.17.0-07f0cdcbb4-20210319X and LibVEX; rerun with -h for copyright info
==19499== Command: ./main HelloWorld
==19499== Parent PID: 16246
==19499== 
--19499-- 
--19499-- Valgrind options:
--19499--    --leak-check=full
--19499--    --show-leak-kinds=all
--19499--    --track-origins=yes
--19499--    --verbose
--19499--    --log-file=valgrind-out.txt
--19499-- Contents of /proc/version:
--19499--   Linux version 5.13.13-arch1-1 (linux@archlinux) (gcc (GCC) 11.1.0, GNU ld (GNU Binutils) 2.36.1) #1 SMP PREEMPT Thu, 26 Aug 2021 19:14:36 +0000
--19499-- 
--19499-- Arch and hwcaps: AMD64, LittleEndian, amd64-cx16-lzcnt-rdtscp-sse3-ssse3-avx-avx2-bmi-f16c-rdrand-rdseed
--19499-- Page sizes: currently 4096, max supported 4096
--19499-- Valgrind library directory: /usr/lib/valgrind
--19499-- Reading syms from /home/tushar/Desktop/main
--19499--    object doesn't have a symbol table
--19499-- Reading syms from /usr/lib/ld-2.33.so
--19499-- Reading syms from /usr/lib/valgrind/memcheck-amd64-linux
--19499--    object doesn't have a dynamic symbol table
--19499-- Scheduler: using generic scheduler lock implementation.
--19499-- Reading suppressions file: /usr/lib/valgrind/default.supp
==19499== embedded gdbserver: reading from /tmp/vgdb-pipe-from-vgdb-to-19499-by-tushar-on-???
==19499== embedded gdbserver: writing to   /tmp/vgdb-pipe-to-vgdb-from-19499-by-tushar-on-???
==19499== embedded gdbserver: shared mem   /tmp/vgdb-pipe-shared-mem-vgdb-19499-by-tushar-on-???
==19499== 
==19499== TO CONTROL THIS PROCESS USING vgdb (which you probably
==19499== don't want to do, unless you know exactly what you're doing,
==19499== or are doing some strange experiment):
==19499==   /usr/lib/valgrind/../../bin/vgdb --pid=19499 ...command...
==19499== 
==19499== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==19499==   /path/to/gdb ./main
==19499== and then give GDB the following command
==19499==   target remote | /usr/lib/valgrind/../../bin/vgdb --pid=19499
==19499== --pid is optional if only one valgrind process is running
==19499== 
--19499-- REDIR: 0x4023890 (ld-linux-x86-64.so.2:strlen) redirected to 0x580bb342 (vgPlain_amd64_linux_REDIR_FOR_strlen)
--19499-- REDIR: 0x4023660 (ld-linux-x86-64.so.2:index) redirected to 0x580bb35c (vgPlain_amd64_linux_REDIR_FOR_index)
--19499-- Reading syms from /usr/lib/valgrind/vgpreload_core-amd64-linux.so
--19499-- Reading syms from /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so
==19499== WARNING: new redirection conflicts with existing -- ignoring it
--19499--     old: 0x04023890 (strlen              ) R-> (0000.0) 0x580bb342 vgPlain_amd64_linux_REDIR_FOR_strlen
--19499--     new: 0x04023890 (strlen              ) R-> (2007.0) 0x048448d0 strlen
--19499-- REDIR: 0x4020070 (ld-linux-x86-64.so.2:strcmp) redirected to 0x4845730 (strcmp)
--19499-- REDIR: 0x4023df0 (ld-linux-x86-64.so.2:mempcpy) redirected to 0x48491a0 (mempcpy)
--19499-- Reading syms from /usr/lib/libc-2.33.so
--19499-- REDIR: 0x490a0b0 (libc.so.6:memmove) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
==19499== Preferring higher priority redirection:
--19499--     old: 0x049dd510 (__memcpy_avx_unalign) R-> (2018.0) 0x04846980 __memcpy_avx_unaligned_erms
--19499--     new: 0x049dd510 (__memcpy_avx_unalign) R-> (2018.1) 0x04848220 memmove
--19499-- REDIR: 0x49095b0 (libc.so.6:strncpy) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x490a3f0 (libc.so.6:strcasecmp) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x4909050 (libc.so.6:strcat) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x4909610 (libc.so.6:rindex) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x490b7a0 (libc.so.6:rawmemchr) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x49237f0 (libc.so.6:wmemchr) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x4923330 (libc.so.6:wcscmp) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x490a210 (libc.so.6:mempcpy) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x490a040 (libc.so.6:bcmp) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x4909540 (libc.so.6:strncmp) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x4909100 (libc.so.6:strcmp) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x490a180 (libc.so.6:memset) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x49232f0 (libc.so.6:wcschr) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x49094a0 (libc.so.6:strnlen) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x49091e0 (libc.so.6:strcspn) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x490a440 (libc.so.6:strncasecmp) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x4909180 (libc.so.6:strcpy) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x490a590 (libc.so.6:memcpy@@GLIBC_2.14) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x4924a40 (libc.so.6:wcsnlen) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x4923370 (libc.so.6:wcscpy) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x4909650 (libc.so.6:strpbrk) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x49090b0 (libc.so.6:index) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x4909460 (libc.so.6:strlen) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x490fc10 (libc.so.6:memrchr) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x490a490 (libc.so.6:strcasecmp_l) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x490a000 (libc.so.6:memchr) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x4923440 (libc.so.6:wcslen) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x4909770 (libc.so.6:strspn) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x490a390 (libc.so.6:stpncpy) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x490a330 (libc.so.6:stpcpy) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x490b7e0 (libc.so.6:strchrnul) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x490a4e0 (libc.so.6:strncasecmp_l) redirected to 0x48331b0 (_vgnU_ifunc_wrapper)
--19499-- REDIR: 0x49da330 (libc.so.6:__strrchr_avx2) redirected to 0x4844310 (rindex)
--19499-- REDIR: 0x49da500 (libc.so.6:__strlen_avx2) redirected to 0x48447b0 (strlen)
--19499-- REDIR: 0x4905320 (libc.so.6:malloc) redirected to 0x483e750 (malloc)
==19499== Conditional jump or move depends on uninitialised value(s)
==19499==    at 0x1091F9: ??? (in /home/tushar/Desktop/main)
==19499==    by 0x109081: ??? (in /home/tushar/Desktop/main)
==19499==    by 0x48A1B24: (below main) (in /usr/lib/libc-2.33.so)
==19499==  Uninitialised value was created by a heap allocation
==19499==    at 0x483E7C5: malloc (vg_replace_malloc.c:380)
==19499==    by 0x1091C9: ??? (in /home/tushar/Desktop/main)
==19499==    by 0x109081: ??? (in /home/tushar/Desktop/main)
==19499==    by 0x48A1B24: (below main) (in /usr/lib/libc-2.33.so)
==19499== 
--19499-- REDIR: 0x49da140 (libc.so.6:__strchrnul_avx2) redirected to 0x4848ca0 (strchrnul)
==19499== Conditional jump or move depends on uninitialised value(s)
==19499==    at 0x48447C8: strlen (vg_replace_strmem.c:469)
==19499==    by 0x48E6FD7: __vfprintf_internal (in /usr/lib/libc-2.33.so)
==19499==    by 0x48D22DE: printf (in /usr/lib/libc-2.33.so)
==19499==    by 0x109092: ??? (in /home/tushar/Desktop/main)
==19499==    by 0x48A1B24: (below main) (in /usr/lib/libc-2.33.so)
==19499==  Uninitialised value was created by a heap allocation
==19499==    at 0x483E7C5: malloc (vg_replace_malloc.c:380)
==19499==    by 0x1091C9: ??? (in /home/tushar/Desktop/main)
==19499==    by 0x109081: ??? (in /home/tushar/Desktop/main)
==19499==    by 0x48A1B24: (below main) (in /usr/lib/libc-2.33.so)
==19499== 
--19499-- REDIR: 0x49dd4f0 (libc.so.6:__mempcpy_avx_unaligned_erms) redirected to 0x4848db0 (mempcpy)
--19499-- REDIR: 0x4905980 (libc.so.6:free) redirected to 0x4841120 (free)
==19499== 
==19499== HEAP SUMMARY:
==19499==     in use at exit: 11 bytes in 1 blocks
==19499==   total heap usage: 2 allocs, 1 frees, 1,035 bytes allocated
==19499== 
==19499== Searching for pointers to 1 not-freed blocks
==19499== Checked 94,736 bytes
==19499== 
==19499== 11 bytes in 1 blocks are definitely lost in loss record 1 of 1
==19499==    at 0x483E7C5: malloc (vg_replace_malloc.c:380)
==19499==    by 0x1091C9: ??? (in /home/tushar/Desktop/main)
==19499==    by 0x109081: ??? (in /home/tushar/Desktop/main)
==19499==    by 0x48A1B24: (below main) (in /usr/lib/libc-2.33.so)
==19499== 
==19499== LEAK SUMMARY:
==19499==    definitely lost: 11 bytes in 1 blocks
==19499==    indirectly lost: 0 bytes in 0 blocks
==19499==      possibly lost: 0 bytes in 0 blocks
==19499==    still reachable: 0 bytes in 0 blocks
==19499==         suppressed: 0 bytes in 0 blocks
==19499== 
==19499== ERROR SUMMARY: 8 errors from 3 contexts (suppressed: 0 from 0)
==19499== 
==19499== 1 errors in context 1 of 3:
==19499== Conditional jump or move depends on uninitialised value(s)
==19499==    at 0x48447C8: strlen (vg_replace_strmem.c:469)
==19499==    by 0x48E6FD7: __vfprintf_internal (in /usr/lib/libc-2.33.so)
==19499==    by 0x48D22DE: printf (in /usr/lib/libc-2.33.so)
==19499==    by 0x109092: ??? (in /home/tushar/Desktop/main)
==19499==    by 0x48A1B24: (below main) (in /usr/lib/libc-2.33.so)
==19499==  Uninitialised value was created by a heap allocation
==19499==    at 0x483E7C5: malloc (vg_replace_malloc.c:380)
==19499==    by 0x1091C9: ??? (in /home/tushar/Desktop/main)
==19499==    by 0x109081: ??? (in /home/tushar/Desktop/main)
==19499==    by 0x48A1B24: (below main) (in /usr/lib/libc-2.33.so)
==19499== 
==19499== 
==19499== 6 errors in context 2 of 3:
==19499== Conditional jump or move depends on uninitialised value(s)
==19499==    at 0x1091F9: ??? (in /home/tushar/Desktop/main)
==19499==    by 0x109081: ??? (in /home/tushar/Desktop/main)
==19499==    by 0x48A1B24: (below main) (in /usr/lib/libc-2.33.so)
==19499==  Uninitialised value was created by a heap allocation
==19499==    at 0x483E7C5: malloc (vg_replace_malloc.c:380)
==19499==    by 0x1091C9: ??? (in /home/tushar/Desktop/main)
==19499==    by 0x109081: ??? (in /home/tushar/Desktop/main)
==19499==    by 0x48A1B24: (below main) (in /usr/lib/libc-2.33.so)
==19499== 
==19499== ERROR SUMMARY: 8 errors from 3 contexts (suppressed: 0 from 0)

输出:

$ ./main HelloWorld
'HeloWrd'

释放后:

==19709== HEAP SUMMARY:
==19709==     in use at exit: 0 bytes in 0 blocks
==19709==   total heap usage: 2 allocs, 2 frees, 1,035 bytes allocated
==19709== 
==19709== All heap blocks were freed -- no leaks are possible
==19709== 
==19709== ERROR SUMMARY: 7 errors from 2 contexts (suppressed: 0 from 0)
==19709== 
==19709== 1 errors in context 1 of 2:
==19709== Conditional jump or move depends on uninitialised value(s)
==19709==    at 0x48447C8: strlen (vg_replace_strmem.c:469)
==19709==    by 0x48E6FD7: __vfprintf_internal (in /usr/lib/libc-2.33.so)
==19709==    by 0x48D22DE: printf (in /usr/lib/libc-2.33.so)
==19709==    by 0x1090A2: ??? (in /home/tushar/Desktop/main)
==19709==    by 0x48A1B24: (below main) (in /usr/lib/libc-2.33.so)
==19709==  Uninitialised value was created by a heap allocation
==19709==    at 0x483E7C5: malloc (vg_replace_malloc.c:380)
==19709==    by 0x1091D9: ??? (in /home/tushar/Desktop/main)
==19709==    by 0x10908E: ??? (in /home/tushar/Desktop/main)
==19709==    by 0x48A1B24: (below main) (in /usr/lib/libc-2.33.so)
==19709== 
==19709== 
==19709== 6 errors in context 2 of 2:
==19709== Conditional jump or move depends on uninitialised value(s)
==19709==    at 0x109209: ??? (in /home/tushar/Desktop/main)
==19709==    by 0x10908E: ??? (in /home/tushar/Desktop/main)
==19709==    by 0x48A1B24: (below main) (in /usr/lib/libc-2.33.so)
==19709==  Uninitialised value was created by a heap allocation
==19709==    at 0x483E7C5: malloc (vg_replace_malloc.c:380)
==19709==    by 0x1091D9: ??? (in /home/tushar/Desktop/main)
==19709==    by 0x10908E: ??? (in /home/tushar/Desktop/main)
==19709==    by 0x48A1B24: (below main) (in /usr/lib/libc-2.33.so)
==19709== 
==19709== ERROR SUMMARY: 7 errors from 2 contexts (suppressed: 0 from 0)

to_set() 中,您为 set_char 分配内存,随后 return 分配给调用者。调用者,在这种情况下 main() 现在必须释放它以避免泄漏:

        char *buff = to_set(argv[1]);
        printf("'%s'\n", buff);
        free(buff);