I'm using Valgrind to check for memory leaks.
Unfortunately I get a Leak_DefinitelyLost
warning.
Attached is a simplified version of my code that reproduces the error:
#include <iostream>
#include <vector>
#include <memory>
#include <unordered_map>
using namespace std;
class Base{
public:
explicit Base(double a){
a_ = a;
}
virtual void fun() = 0;
protected:
double a_;
};
class Derived_A : public Base{
public:
Derived_A(double a, vector<double> b, vector<double> c): Base(a), b_{b}, c_{c}{
}
void fun() override{
cout << "Derived_A " << a_ << endl;
}
private:
vector<double> b_;
vector<double> c_;
};
class Derived_B : public Base{
public:
Derived_B(double a, double b, double c): Base(a), b_{b}, c_{c}{
}
void fun() override{
cout << "Derived_B " << a_ << endl;
}
private:
double b_;
double c_;
};
int main() {
unordered_map<string, unique_ptr<Base> > m;
for(int i=0; i<10; ++i){
unique_ptr<Base> o;
if(i%2 == 0){
vector<double> b{1., 2., 3.};
vector<double> c{4., 5., 6.};
o = make_unique<Derived_A>(i, move(b), move(c));
m[to_string(i)] = move(o);
}else{
double b = 1.;
double c = 2.;
o = make_unique<Derived_B>(i, b, c);
m[to_string(i)] = move(o);
}
}
for(const auto &any:m){
any.second->fun();
}
return 0;
}
The lost happens during the make_unique
call:
Leak_DefinitelyLost
vg_replace_malloc.c
240 bytes in 10 blocks are definitely lost in loss record 1 of 1
operator new(unsigned long)
__gnu_cxx::new_allocator<double>::allocate(unsigned long, void const*)
std::allocator_traits<std::allocator>::allocate(std::allocator<double>&, unsigned long)
std::_Vector_base<double, std::allocator>::_M_allocate(unsigned long)
std::_Vector_base<double, std::allocator>::_M_create_storage(unsigned long)
std::_Vector_base<double, std::allocator>::_Vector_base(unsigned long, std::allocator<double> const&)
std::vector<double, std::allocator>::vector(std::vector<double, std::allocator> const&)
Derived_A::Derived_A(double, std::vector<double, std::allocator>, std::vector<double, std::allocator>)
std::_MakeUniq<Derived_A>::__single_object std::make_unique<Derived_A, int&, std::vector, std::vector>(int&, std::vector<double, std::allocator>&&, std::vector<double, std::allocator>&&)
main
I'm not sure what I'm doing wrong. Can someone please clarify where the error occurs?
(I'm calling Valgrind from CLion 2018.1.5, Valgrind 3.13.0.)
Valgrind Memcheck is a tool that detects memory leaks and memory errors. Some of the most difficult C bugs come from mismanagement of memory: allocating the wrong size, using an uninitialized pointer, accessing memory after it was freed, overrunning a buffer, and so on.
The best way to avoid memory leaks in C++ is to have as few new/delete calls at the program level as possible – ideally NONE. Anything that requires dynamic memory should be buried inside an RAII object that releases the memory when it goes out of scope.
The memory leak occurs, when a piece of memory which was previously allocated by the programmer. Then it is not deallocated properly by programmer. That memory is no longer in use by the program. So that place is reserved for no reason. That's why this is called the memory leak.
Base
is missing a virtual destructor, so you invoke UB.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With