I expect next code works. And do not introduce memory leak. I test it in three compilers, and it fails with Microsoft Visual Studio 2017 (15.4.5) I try also in online compiler (http://rextester.com/l/cpp_online_compiler_visual) and receive same fail. Next code work nice in clang++6.0 and g++8.2 but in msvc2017 as I see there is a memory leak. Why is so? Should I report bug to Microsoft, and what c++ standard say about it?
#include <cassert>
#include <iostream>
#include <cstdlib>
#include <new>
int global_counter = 0;
void * operator new(std::size_t n) noexcept(false) // _THROW_BAD_ALLOC //
throw(std::bad_alloc)
{
void* result = malloc(n);
++global_counter;
return result;
}
void operator delete(void * p) noexcept(true)
{
free(p);
--global_counter;
}
void operator delete(void* p, std::size_t) noexcept(true)
{
free(p);
--global_counter;
}
struct A
{
A(int i)
:value(i){
std::cout << "constructor A" << std::endl;
}
~A()noexcept(false){throw value;}
int value;
};
int main()
{
int start_value = global_counter;
std::cout << "start global_counter = " << global_counter << std::endl;
{
try
{
//A a1();
A* a2{new A(2)};
std::cout << "before ex global_counter = " << global_counter << std::endl;
delete a2;
} catch (int i)
{
std::cout << "in catch ex global_counter = " << global_counter << std::endl;
std::cout << "exception value: " << i << std::endl;
}
}
std::cout << "end global_counter = " << global_counter << std::endl;
assert(global_counter == start_value);
return 0;
}
compile command for msvc:
cl.exe source_file.cpp -o a.exe /EHsc /MD /link /std:c++17
compile command for g++(linux):
g++ prog.cc -Wall -Wextra -std=gnu++2a
compile command for clang++(linux):
clang++ prog.cc -Wall -Wextra -std=gnu++2a