以下代码使用 Dlang 语言编写,用于测试 strdup 函数是否会导致内存泄漏:

@nogc nothrow:
extern (C):
__gshared:
public import core.stdc.stdio;
public import core.stdc.string;

char* reverse(char* str)
{
    ulong length = strlen(str);
    for (ulong i = 0, j = length - 1; i < j; i++, j--)
    {
        char temp = str[i];
        str[i] = str[j];
        str[j] = temp;
    }
    return str;
}

int main()
{

    char* str = 'helloworld'.strdup;
    reverse(str);
    printf('%s',str);

    return 0;
}

使用 Valgrind 工具测试后,得到了以下提示:

==2167856== Memcheck, a memory error detector
==2167856== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==2167856== Using Valgrind-3.21.0 and LibVEX; rerun with -h for copyright info
==2167856== Command: ./anice.exe
==2167856== 
dlrowolleh==2167856== 
==2167856== HEAP SUMMARY:
==2167856==     in use at exit: 80 bytes in 3 blocks
==2167856==   total heap usage: 9 allocs, 6 frees, 1,243 bytes allocated
==2167856== 
==2167856== 16 bytes in 1 blocks are still reachable in loss record 1 of 3
==2167856==    at 0x484D5D5: calloc (vg_replace_malloc.c:1554)
==2167856==    by 0x430588: rt.sections_elf_shared._tlsRanges() (in /home/chenfa/dev_proj/d_proj/test_to_c/5_22/anice.exe)
==2167856==    by 0x42D86C: _d_dso_registry (in /home/chenfa/dev_proj/d_proj/test_to_c/5_22/anice.exe)
==2167856==    by 0x42D6A5: ??? (in /home/chenfa/dev_proj/d_proj/test_to_c/5_22/anice.exe)
==2167856==    by 0x45C9EC: __libc_csu_init (in /home/chenfa/dev_proj/d_proj/test_to_c/5_22/anice.exe)
==2167856==    by 0x49B1E1B: __libc_start_main@@GLIBC_2.34 (libc-start.c:375)
==2167856==    by 0x42D548: ??? (in /home/chenfa/dev_proj/d_proj/test_to_c/5_22/anice.exe)
==2167856==    by 0x1FFEFFF857: ???
==2167856==    by 0x1B: ???
==2167856== 
==2167856== 16 bytes in 1 blocks are still reachable in loss record 2 of 3
==2167856==    at 0x484D7E1: realloc (vg_replace_malloc.c:1649)
==2167856==    by 0x42E4E5: core.internal.container.common.xrealloc(void*, ulong) (in /home/chenfa/dev_proj/d_proj/test_to_c/5_22/anice.exe)
==2167856==    by 0x42E30D: core.internal.container.array.Array!(void[]).Array.insertBack!().insertBack(void[]) (in /home/chenfa/dev_proj/d_proj/test_to_c/5_22/anice.exe)
==2167856==    by 0x42D88E: _d_dso_registry (in /home/chenfa/dev_proj/d_proj/test_to_c/5_22/anice.exe)
==2167856==    by 0x42D6A5: ??? (in /home/chenfa/dev_proj/d_proj/test_to_c/5_22/anice.exe)
==2167856==    by 0x45C9EC: __libc_csu_init (in /home/chenfa/dev_proj/d_proj/test_to_c/5_22/anice.exe)
==2167856==    by 0x49B1E1B: __libc_start_main@@GLIBC_2.34 (libc-start.c:375)
==2167856==    by 0x42D548: ??? (in /home/chenfa/dev_proj/d_proj/test_to_c/5_22/anice.exe)
==2167856==    by 0x1FFEFFF857: ???
==2167856==    by 0x1B: ???
==2167856== 
==2167856== 48 bytes in 1 blocks are still reachable in loss record 3 of 3
==2167856==    at 0x484D7E1: realloc (vg_replace_malloc.c:1649)
==2167856==    by 0x4599CD: core.internal.gc.impl.conservative.gc.gc_precise_ctor() (in /home/chenfa/dev_proj/d_proj/test_to_c/5_22/anice.exe)
==2167856==    by 0x45C9EC: __libc_csu_init (in /home/chenfa/dev_proj/d_proj/test_to_c/5_22/anice.exe)
==2167856==    by 0x49B1E1B: __libc_start_main@@GLIBC_2.34 (libc-start.c:375)
==2167856==    by 0x42D548: ??? (in /home/chenfa/dev_proj/d_proj/test_to_c/5_22/anice.exe)
==2167856==    by 0x1FFEFFF857: ???
==2167856==    by 0x1B: ???
==2167856== 
==2167856== LEAK SUMMARY:
==2167856==    definitely lost: 0 bytes in 0 blocks
==2167856==    indirectly lost: 0 bytes in 0 blocks
==2167856==      possibly lost: 0 bytes in 0 blocks
==2167856==    still reachable: 80 bytes in 3 blocks
==2167856==         suppressed: 0 bytes in 0 blocks
==2167856== 
==2167856== For lists of detected and suppressed errors, rerun with: -s
==2167856== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

分析 Valgrind 的输出,可以看到没有出现 definitely lostindirectly lostpossibly lost 的情况,这意味着代码中没有明显的内存泄漏问题。但是还有 80 字节的内存仍然可以访问,被列为 still reachable,这可能是因为程序结束时没有释放所有分配的内存,或者是因为某些全局变量持有了一些内存。

在这种情况下,可以考虑在程序结束时手动释放所有使用的内存来解决这个问题。例如,可以在 main 函数的最后添加 free(str); 语句来释放 str 指针指向的内存。

@nogc nothrow:
extern (C):
__gshared:
public import core.stdc.stdio;
public import core.stdc.string;

char* reverse(char* str)
{
    ulong length = strlen(str);
    for (ulong i = 0, j = length - 1; i < j; i++, j--)
    {
        char temp = str[i];
        str[i] = str[j];
        str[j] = temp;
    }
    return str;
}

int main()
{

    char* str = 'helloworld'.strdup;
    reverse(str);
    printf('%s',str);

    free(str);
    return 0;
}

通过手动释放内存,可以避免内存泄漏问题。需要注意的是,在使用 strdup 函数时,需要确保在使用完分配的内存后及时释放,以避免内存泄漏。


原文地址: https://www.cveoy.top/t/topic/oflx 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录