为什么在以下情况下valgrind memcheck不发出重叠错误?

pcww981p  于 2023-01-25  发布在  其他
关注(0)|答案(1)|浏览(116)

Valgrind's Memcheck工具中,它表示
下面的C库函数将一些数据从一个内存块复制到另一个内存块(或类似的东西):memcpy,strcpy,strncpy,strcat,strncat。src和dst指针所指向的块不允许重叠。POSIX标准沿着有这样的措辞“如果复制发生在重叠的对象之间,则行为未定义。”因此,Memcheck会对此进行检查。
因此,我认为如果使用memcpy在重叠地址之间进行复制,可能会从valgrind memcheck中得到此错误。
所以我写了下面的代码,但是无论是C++版本还是C版本,我都不能让valgrind memcheck检查重叠错误。

int main()
{
    // The C++ version
    int * x = new int[3]{1, 2, 3};
    memcpy(x + 1, x, 2);
}

int main()
{
    // The C version 
    void * y = malloc(10);
    memset(y, 0, 10);
    memcpy(y + 1, y, 2);
}

实际上,如果我运行以下命令

valgrind --tool=memcheck --leak-check=full --track-origins=yes ./tt

那我就

==33771== Memcheck, a memory error detector
==33771== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==33771== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==33771== Command: ./tt
==33771==
==33771==
==33771== HEAP SUMMARY:
==33771==     in use at exit: 10 bytes in 1 blocks
==33771==   total heap usage: 2 allocs, 1 frees, 72,714 bytes allocated
==33771==
==33771== 10 bytes in 1 blocks are definitely lost in loss record 1 of 1
==33771==    at 0x4C29F73: malloc (vg_replace_malloc.c:309)
==33771==    by 0x4006C8: main
==33771==
==33771== LEAK SUMMARY:
==33771==    definitely lost: 10 bytes in 1 blocks
==33771==    indirectly lost: 0 bytes in 0 blocks
==33771==      possibly lost: 0 bytes in 0 blocks
==33771==    still reachable: 0 bytes in 0 blocks
==33771==         suppressed: 0 bytes in 0 blocks
==33771==
==33771== For lists of detected and suppressed errors, rerun with: -s
==33771== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

我想知道为什么,在什么情况下valgrind可以输出重叠错误?

sg2wtvxw

sg2wtvxw1#

即使只进行调试构建,编译器也会发现不调用memcpy更高效:
https://godbolt.org/z/P9s664Gx8
GCC也是类似的,直到复制了12个字节,我才得到对memcpy的调用。

相关问题