In Valgrind's Memcheck tool, it says
The following C library functions copy some data from one memory block to another (or something similar): memcpy, strcpy, strncpy, strcat, strncat. The blocks pointed to by their src and dst pointers aren't allowed to overlap. The POSIX standards have wording along the lines "If copying takes place between objects that overlap, the behavior is undefined." Therefore, Memcheck checks for this.
So I think if I use memcpy
to copy between overlapped addresses, I can get this error from valgrind memcheck.
So I write the following code. However, either in the C++ version or the C version, I can't make valgrind memcheck for a overlap error.
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);
}
In fact, if I run by the following command
valgrind --tool=memcheck --leak-check=full --track-origins=yes ./tt
Then I will get
==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)
I wonder why, and in what situation can valgrind output an overlap error?
Even with just a debug build the compiler sees that it's more efficient not to make a call to memcpy
:
https://godbolt.org/z/P9s664Gx8
GCC is similar. I don't get a call to memcpy
until 12 bytes are copied.