I am learning valgrind framework and I decided to run it on my own minor test case. Here is following program, which forces deletion extra object from heap (I running it on AMD64/LINUX):
#include <iostream>
using namespace std;
struct Foo
{
Foo(){ cout << "Creation Foo" << endl;}
~Foo(){ cout << "Deletion Foo" << endl;}
};
int main()
{
Foo* ar = new Foo[3];
*(reinterpret_cast<int*>(ar)-2) = 4;
delete[] ar;
return 0;
}
But result of execution of valgrind really confused me:
$ valgrind --leak-check=full ./a.out -v
==17649== Memcheck, a memory error detector
==17649== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==17649== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==17649== Command: ./a.out -v
==17649==
Creation Foo
Creation Foo
Creation Foo
Deletion Foo
Deletion Foo
Deletion Foo
Deletion Foo
==17649==
==17649== HEAP SUMMARY:
==17649== in use at exit: 72,704 bytes in 1 blocks
==17649== total heap usage: 3 allocs, 2 frees, 73,739 bytes allocated
==17649==
==17649== LEAK SUMMARY:
==17649== definitely lost: 0 bytes in 0 blocks
==17649== indirectly lost: 0 bytes in 0 blocks
==17649== possibly lost: 0 bytes in 0 blocks
==17649== still reachable: 72,704 bytes in 1 blocks
==17649== suppressed: 0 bytes in 0 blocks
==17649== Reachable blocks (those to which a pointer was found) are not shown.
==17649== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==17649==
==17649== For counts of detected and suppressed errors, rerun with: -v
==17649== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
It seems like that valgrind (version 3.13.0)did not detect any memory corruption?
UPD: I compiled main.cpp
with command g++ -g main.cpp
*(reinterpret_cast<int*>(ar)-2) = 4;
is a potential strict aliasing violation causing undefined behavior and a potential target for optimization in Release mode throwing out entire line. How did you compile this code? – user7860670