#include <iostream>
#include <fstream>
#include <cstdio>
using namespace std;
class Derived
{
public:
Derived()
{
cout<< "Initialize...\n";
}
~Derived()
{
cout<< "Finalize...\n";
}
};
static Derived *obj=new Derived();
int main()
{
cout<<"Main Started::\n";
}
I'm trying to get the output as:
Initialize
MainStarted
Finalize
But getting:
Initialize
MainStarted
I tried to debug but its not getting into destructor. So I'm unable solve this problem.
You need to use
static Derived obj;
instead of
static Derived *obj=new Derived();
Now you create object with new, and never call delete, thus object will never be properly deleted.
Or you can use boost::scoped_ptr if you need heap allocated object for some reason.
static Derived *obj=new Derived();
That's a leak - the object has dynamic storage duration (since you've created it with new), and nothing deletes it, so it will never be destroyed.
If you want it to be destroyed automatically, then give the object static storage duration:
static Derived obj;
Alternatively, instead of defining a class with a destructor, you can use std::atexit to register an arbitrary function to call when the program exits:
#include <iostream>
#include <cstdlib> // for atexit
void goodbye() {std::cout << "Goodbye\n";}
int main() {
std::atexit(goodbye);
std::cout << "Hello\n";
}
Don't make the derived object a pointer. Since C++ is not java, there is little need for new in your case. But if you create the Derived on the heap, you'll have to make sure that it gets destroyed properly, by using RAII, i.e. a smart pointer. In your code you have a memory leak, the destructor of *obj gets never called.
Examples for how to do it right:
static Derived obj; //non-heap version
//C++03 auto_ptr, now deprecated:
static std::auto_ptr<Derived> obj(new Derived());
//C++11 smart pointers:
static std::unique_ptr<Derived> obj(new Derived());
static auto obj = std::make_shared<Derived>();
//Boost smart pointers, C++03 compatible:
static boost::shared_ptr<Derived> obj = boost::make_shared<Derived>();
static boost::scoped_ptr<Derived> obj(new Derived());
Pick one (the first, preferably).
Edit: But before you do any of these, you should give a really good reason for using that global variable.
you are using static Derived *obj=new Derived() but instead of use static Derived obj1 this will print as per your requirements.
Related
I have just started using std::variant in my projects. I have a doubt. What will the destructor of std::variant do in the code shown below. Variant holds a void* data. Once variant goes out of scope, I think it will only free the memory of void* but not the actual object the pointer was pointing to. So there will be memory leak in this case. I would like to know if my understanding is correct or not.
#include <iostream>
#include <memory>
#include <variant>
using namespace std;
class A {
public:
~A(){
cout<<"Destructor called"<<endl;
}
};
int main() {
std::variant<void*> data;
A* b = new A();
data = (void*)b;
return 0;
}
When the variant destructor fires, it will call the destructor for whatever type of item is stored in the variant at that point. If that’s a void*, then C++ will say “okay, I will clean up the void*, and since that’s a primitive type, that’s a no-op.” It won’t look at the void*, realize that it’s actually a pointer to an A, and then delete the pointer as though it’s an A*.
The comments have pointed out that it’s fairly unusual to use a variant of a void*. A void* means “I’m pointing at something, and it’s up to you as the user to keep track of what it is and do the appropriate casting and resource management.” A variant means “I’m holding one of the following actual things, and I want C++ to remember which one and to do the appropriate resource management for me.” You may want to rethink your design, as there might be an easier way to do whatever you’re aiming to do here.
You are correct. The only pointer owning classes in the standard library that actually does delete (or delete[]) on pointers are the smart pointers.
std::variant is supposed to support you to hold one object of any number of types and primarily not pointers to objects. If the variant contains pointers, it means that some other object owns the data and is responsible for deleting it.
A std::variant capable of holding only one type is rarely useful either. You can declare the variable as a normal variable of that type in that case.
Here's one example of using a std::variant capable of holding objects of two unrelated types, and destruction will happen as expected.
#include <iostream>
#include <variant>
class A {
public:
~A() { std::cout << "A destructor called\n"; }
};
class B {
public:
B() {}
B(const B&) = default;
B& operator=(const B&) = default;
~B() { std::cout << "B destructor called\n"; }
};
int main() {
std::variant<A, B> data; // now holds a default constructed A
data = B(); // deletes the A and now holds a default constructed B
std::cout << "---\n";
}
Output:
A destructor called // in "data = B()", the A must be destroyed
B destructor called // the temporary B used in "data = B()"
---
B destructor called // the B in the variant when the variant goes out of scope
I should delete new instances in C++, right?
class C {
public:
void hello() {...};
};
If I have an instance of the class above, I may have to use it like
C* c = new C();
c->hello();
delete c;
right? How about this:
(new C())->hell();
Can I do this? Is destructor automatically called and free the memory?
No, destructor is not called automatically because you never call delete. However you can create a smart pointer that will do it for you at one go:
::std::make_unique<C>()->helo();
In modern c++ there is no reason to new-up resources anymore. Instead you can use the memory library as following:
#include <memory>
#include <iostream>
class C
{
public:
C(int a) : _a(a) { }
void printA() { std::cout << _a << std::endl; }
private:
int _a;
};
std::make_unique<C>(3)->printA(); // prints 3
// or via variable
auto c = std::make_unique<C>(123);
c->printA(); // prints 123
In here, the resources are already taken care off and you can't forget deleting something you allocated somewhere else.
No in the second case the destructor will not be called and also you will have memory leak. The destructor of a dynamically allocated objects is called only when explicitly calling delete.
I want to create a singleton class such that when all pointers to the class go away the destructor is called.
#include <memory>
#include <iostream>
class MyClass {
public:
uint8_t str[50]; //some random data
MyClass() {LOG("constructor Called"); }
~MyClass() {LOG("destructor Called");}
static std::shared_ptr<MyClass> &Get();
private:
static std::shared_ptr<MyClass> instance;
};
std::shared_ptr<MyClass> MyClass::instance=NULL;
std::shared_ptr<MyClass> &MyClass::Get()
{
if (instance == NULL)
{
instance= std::shared_ptr<MyClass>(new MyClass());
return instance;
}
return instance;
}
int main()
{
std::shared_ptr<MyClass> &p1 =MyClass::Get();
printf("We have %" PRIu32, p1.use_count());
if (1)
{
std::shared_ptr<MyClass> &p2 =MyClass::Get();//this should not
// create a new class
printf("We have %" PRIu32, p1.use_count()); //this should be two...
printf("We have %" PRIu32, p2.use_count()); //this should be two...
//when p1 goes out of scope here it should not call destructor
}
printf("We have %" PRIu32, p1.use_count());
//now destructor should be called
return 0;
}
The above code does not work as the static instance is a smart pointer and never goes out of scope, hence the destructor is never called.
What I would like to do is when the static instance is first created to return this instance of a smart pointer and then every call there after return a copy of this smart pointer.
A std::weak_ptr is what you're looking for.
By changing the instance to be a weak_ptr, it does not count as an owner to the shared pointer; meaning that once all other references have been released the object is destroyed. That said, it does make your "Get" function a little more complex, in that you must attempt to get a shared_ptr from the weak ptr, then on success return it, or on failure create a new one, re-assign instance to that ptr and return.
You can find more here
As a separate note, the destructor of your static member will be called, just not before main returns. Most people accept this feature of a static since once main returns they don't really care what happens as long as the application doesn't crash (although statics using other statics tends to result in exactly that)
I need to have a singleton class as I need to initialise some variables only once. I have a problem when I can't to clean up the class as it is crashing. Here is a cut down version of my class:
#include "stdafx.h"
#include <iostream>
class MyClass
{
public:
MyClass();
virtual ~MyClass();
static MyClass& Instance();
void DoSomething();
};
MyClass::MyClass()
{
std::cout<<"MyClass constructor"<<std::endl;
//initialise some stuff here
}
MyClass::~MyClass()
{
std::cout<<"MyClass destructor"<<std::endl;
//clean up some stuff here
}
MyClass& MyClass::Instance()
{
static MyClass _instance;
return _instance;
}
void MyClass::DoSomething()
{
std::cout<<"Do something"<<std::endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
MyClass& myClass = MyClass::Instance();
myClass.DoSomething();
delete &myClass;
return 0;
}
When I call the delete &myClass the destructor gets called and then it blows up like so:
I have investigated and I think that I shouldn't be calling delete on an object that has not been created using new. Is this correct??
Is the answer simply don't use any delete and let the destructor be called automatically when it goes out of scope (When main returns)?
I shouldn't be calling delete on an object that has not been created using new.
Absolutely. It's a static object, which will be destroyed automatically at the end of the program. There's no need (and no way) to destroy it yourself.
(Note that, being static, it's not destroyed when it goes out of scope when Instance() returns. Instead it's destroyed at the end of the program, after returning from main() or calling exit()).
When the static object goes out of scope, they will be deleted automatically, so dont bother calling delete on a static object and you should be fine
Your error is due to the delete (as mentioned by others).
I need to have a singleton class as I need to initialise some variables only once.
No, you really (really, really) don't. Singletons solve the problem of centralizing values/settings, while introducing hidden state, tightening module coupling, hiding module dependencies and rendering code untestable.
Consider using dependency injection instead.
My code is like following, basically I am using some external library and embed some class objects from this library to myClass, then do things with OBJ,
#include "extern_lib.h" //some library
class myClass
{
public:
extern_class *obj1;
extern_class *obj2;
double arr[3];
};
int main()
{
myClass *OBJ= new myClass();
OBJ->obj1 = new extern_class(arg1...);
OBJ->obj2 = new extern_class(arg2...);
//do something like
OBJ->obj1->extern_fun1(arg1...);
OBJ->obj2->extern_fun2(arg2...);
//delete
delete OBJ;
return 0;
}
I would like to know,
1- in order to free all the objects, is it enough to delete OBJ?
2- is there better ways to write this code?
No, it is not enough. You have to call delete for every new you place in your code explicitely.
Use smart pointers like std::unique_ptr or better, use RAII. To clarify that: smart pointers and RAII are not even only better ways of doing so, they are the ways of doing it correctly in modern C++.
Here's an adequate example with RAII:
#include "extern_lib.h"
class myClass
{
public: // note that public members are possibly bad design (depending on your situation)
extern_class obj1;
extern_class obj2;
double arr[3];
};
int main()
{
myClass foo;
foo.obj1.extern_fun(arg1...);
foo.obj2.extern_fun(arg2...);
return 0;
}
Please note that it's not possible to use RAII in every situation. If you run into such, use smart pointers as stated:
#include "extern_lib.h"
class myClass
{
public: // note that public members are possibly bad design (depending on your situation)
std::unique_ptr<extern_class> obj1;
std::unique_ptr<extern_class> obj2;
double arr[3];
};
int main()
{
myClass foo;
foo.obj1 = std::unique_ptr<extern_class>(new extern_class(arg1...));
foo.obj2 = std::unique_ptr<extern_class>(new extern_class(arg2...));
foo.obj1->extern_fun(arg1...);
foo.obj2->extern_fun(arg2...);
return 0;
}
In order to free all the objects, is it enough to delete OBJ?
No, this will produce a resource leak as the (default) destructor of myClass doesn't care about deleting the pointer members.
Is there better ways to write this code?
Yes, use smart pointers. For example:
class myClass
{
public:
std::unique_ptr<extern_class> obj1;
std::unique_ptr<extern_class> obj2;
double arr[3];
};
In general, try to make resources owned by classes. That is, allocate them in the constructor and deallocate them in the destructor. The standard library's smart pointers will already do that job for you. Avoid managing more than one resource inside a single class.
By the way: If your example is not contrived and you are really not using polymorphism at all, then just get rid of all those news and simply use variables with automatic storage duration. C++ is not Java.
Update: Here is (one way of) how to get rid of new if polymorphism is not needed:
class myClass
{
public:
extern_class obj1;
extern_class obj2;
double arr[3];
myClass(type arg1a, ..., type arg2a, ...) : obj1(arg1a, ...), obj2(arg2a, ...)
// ^^^^ member initializer list ^^^^
{
}
};
The key is to create the member objects as part of the process of creating myClass by using a so-called member initializer list. If you are programming C++11, prefer writing obj1 {arg1a, ...}, obj2 {arg2a, ...} for consistency. (The old syntax still works equally well, however.)
Likewise in your main function:
int
main()
{
myClass mc(arg1a, ..., arg2a, ...); // (1)
mc.obj1.extern_func(...);
mc.obj2.extern_func(...);
return 0; // (2)
}
At line (1), we create an instance of myClass on the stack using our new constructor that will create the members obj1 and obj2 correctly. The compiler-generated default constructor of myClass will correctly destruct mc.obj1 and mc.obj2 as mc goes out of scope on line (2). Again, in C++11 line (1) can be written more cleanly as myClass mc {arg1a, ..., arg2a, ...};.