sorry but I cant understand why 2 times destructor called?
#include <iostream>
#include <thread>
class myClass
{
public:
int integer;
void operator()()
{
std::cout << "class: " << integer << "\t" << std::this_thread::get_id() << std::endl;
}
myClass(int h)
: integer{h}
{
}
~myClass()
{
std::cout << "MyClass by int: " << integer << " destroyed!" << std::endl;
}
};
bool myFunc(int x)
{
myClass tempClass(x);
std::thread one(tempClass);
one.join();
if (x <= 0)
return 0;
else
return myFunc(x - 1);
}
int main()
{
myFunc(10);
return 0;
}
note : I'm just trying in MultiThreads. (training)
and one more problem is that why before joining thread , my class has destroyed!
In the line
std::thread one(tempClass);
a copy of tempClass is created. Later on, both instances of myClass are destroyed.
You can pass tempClass by reference by using std::ref, but then you have to guarantee that tempClass remains valid (e.g. does not go out of scope, is brought in an invalid state by the main thread) throughout the life time of your thread (one).
You can also move tempClass into the other thread. You would still end up with two destructor calls and it would hardly make any difference in your case, but if myClass is difficult to copy, it can make a difference. In that case, you may want to read up on move semantics.
Related
I am having the below code :
std::vector<std::function<void()>> functors;
class Bar
{
public :
Bar(const int x, const int y):d_x(x),d_y(y){}
~Bar(){
cout << "Destructing Bar" << endl;
}
void addToQueue()
{
const auto job = [=](){
cout << "x:" << d_x << " y: " << d_y;
};
functors.push_back(job);
}
private :
int d_x,d_y;
};
void example()
{
cout << "Hello World" << endl;
{
shared_ptr<Bar> barPtr = make_shared<Bar>(5,10);
barPtr->addToQueue();
}
cout << "Out of scope. Sleeping" << endl;
usleep(1000);
functors[0]();
}
The output is as expected :
Hello World
Destructing Bar
Out of scope. Sleeping
x:5 y: 10
I am now capturing by value, which is why I assume when the Bar object gets destroyed, I can still access its member variables. If the above is right, I am expecting the below change to give me UB:
const auto job = [&](){
However, I still see the same result. Why is that? Have i understood something wrong?
EDIT Further on the above, what I want to understand from this example - is how can I have access to a class member variables in a lambda function even if object has been destroyed? I am trying to avoid UB and thought that passing by value is the way to go, but can't prove that the opposite isn't working.
This kind of confusion iss probably one of the reasons why C++20 deprecated the implicit capture of this with [=]. You can still capture [this], in which case you have the usual lifetime issues with an unmanaged pointer. You can capture [*this] (since C+=17), which will capture a copy of *this so you don't have lifetime issues.
You could also use std::enable_shared_from_this since you're using a std::shared_ptr in example, but that's a bit more complicated. Still, it would avoid both the copy and the UB when the lifetime issues.
In these examples you are capturing this and not any of the fields.
When capturing this, by design, it is never captured by copying the object or the fields.
The best way to capture a field by value is:
[field = field] () { }
Both versions of your code have undefined behaviour. barPtr is the only owner of the shared_ptr so your object is destructed at the end of the scope containing barPtr. Executing the lambda which has captured this from the object in barPtr has undefined behaviour.
The usual way to prevent this is for the lambda to capture a shared_pointer from shared_from_this to keep the object alive. E.g:
#include <vector>
#include <functional>
#include <iostream>
#include <memory>
std::vector<std::function<void()>> functors;
class Bar : public std::enable_shared_from_this<Bar>
{
public :
Bar(const int x, const int y):d_x(x),d_y(y){}
~Bar(){
std::cout << "Destructing Bar\n";
}
void addToQueue()
{
auto self = shared_from_this();
const auto job = [this, self](){
std::cout << "x:" << d_x << " y: " << d_y << "\n";
};
functors.push_back(job);
}
private :
int d_x,d_y;
};
int main()
{
std::cout << "Hello World\n";
{
std::shared_ptr<Bar> barPtr = std::make_shared<Bar>(5,10);
barPtr->addToQueue();
}
std::cout << "Out of scope\n";
functors[0]();
}
By capturing self the shared_ptr will now survive for at least as long as the lambda does.
I am searching for a way to start multiple threads whose exact number can only be determined at runtime. The threads are not dependent on each other, so it's a fire-and-forget kind of problem.
The threads do need some context which is stored as internal variables of a class (Foo). Some of these variables are references. The class also holds a method that should be executed as the thread function (bar).
#include <iostream>
#include <string>
#include <vector>
#include <thread>
class Foo
{
public:
Foo(int a){
std::cout << "Created" << std::endl;
m_a = new int(a);
}
~Foo(){
std::cout << "Destroyed" << std::endl;
delete m_a;
}
void bar() {
std::cout << "Internal var: " << *m_a << std::endl;
}
private:
int* m_a;
};
int main() {
for(int i = 0; i < 5; i++) {
std::thread t(&Foo::bar, std::ref(Foo(i)));
// the threads will be joined at a later point, this is for demo purposes
}
return 0;
}
I get a compile error at this point:
error: use of deleted function ‘void std::ref(const _Tp&&) [with _Tp = Foo]’
I get it that this error is caused because of the temporary nature of the object created in the for-loop. But if I remove the std::ref function, I get a segfault: double free or corruption (fasttop)
I am sure that there must be a way of doing this, but I am unaware of that. I would expect some output like (probably in this order, but not guaranteed):
Created
Internal var: 0
Destroyed
Created
Internal var: 1
Destroyed
...
Thanks!
Problem 1: Foo is missing a copy/move constructor. See The rule of three/five/zero.
Add a copy constructor:
Foo(Foo const& that) : m_a(new int(*that.m_a)) {}
And/or a move constructor:
Foo(Foo && that) : m_a(that.m_a) { that.m_a = nullptr; }
Problem 2: Foo(i) is a temporary instance of Foo, it lives until the end of the full-expression (the ;).
std::thread t(&Foo::bar, std::ref(Foo(i)));
// ^
// Foo(i) is dead at this point while the thread is starting!
You want it to live longer than that, in order to be usable inside the thread.
For example, like this (also answers your question about creating threads in a loop):
int main() {
std::vector<Foo> inputs;
std::vector<std::thread> threads;
for(int i = 0; i < 5; i++) {
inputs.emplace_back(i);
threads.emplace_back(&Foo::bar, &inputs.back());
}
for (auto& t : threads) {
t.join();
}
}
Note: std::ref(Foo(i)) doesn't compile because it has protection against returning references to temporaries (precisely to prevent issues like these).
Here is a minimaly fixed version of your code:
it includes the move ctor for Foo class (and explicitely deletes copy ctor)
it moves the threads into a vector
it joins the threads
Code:
#include <string>
#include <vector>
#include <thread>
#include <iostream>
class Foo
{
public:
Foo(int a) {
std::cout << "Created" << std::endl;
m_a = new int(a);
}
~Foo() {
if (m_a != NULL) {
std::cout << "Destroyed" << std::endl;
delete m_a;
}
}
Foo(const Foo& other) = delete; //not used here
Foo(Foo&& other) {
std::cout << "Move ctor" << '\n';
m_a = other.m_a;
other.m_a = nullptr;
}
void bar() {
std::cout << "Internal var: " << *m_a << std::endl;
}
private:
int* m_a;
};
int main() {
std::vector<std::thread> vec;
for (int i = 0; i < 5; i++) {
std::thread t(&Foo::bar, Foo(i));
vec.push_back(std::move(t));
}
for (auto& t : vec) {
t.join();
}
return 0;
}
The chief design failure seems that t is a variable inside the loop. That means it's destroyed at the end of each iteration - you never have 5 std::thread instances at the same time. Also, you fail to call join on those threads.
The std::ref apparently hides this problem and replaces it with another problem, but your original thread creation was correct: std::thread t(&Foo::bar, Foo(i)).
You probably want a std::list<std::thread>, and use std::list::emplace_back to create a variable amount. std::list<std::thread> allows you to remove threads in any order from the list.
I have used function objects to find out what happens to the object that gets passed, and how it effects the state of the object. Here is a snippet of the test code:
#include <iostream>
//#include <boost/function.hpp>
//using boost::function;
#include <functional>
using std::function;
using std::bind;
struct A {
A() { std::cout << "Creating..." << "\n"; }
void operator()() { call(); }
void call() { std::cout << "Executing call..." << "\n"; }
virtual ~A() { std::cout << "Destroying" << "\n"; }
};
typedef function<void ()> Func;
struct B{
Func f;
B(Func ff) : f(ff) {}
void call() {f();}
};
int main(int argc, char *argv[])
{
{
A a;
B b(a);
for (int i = 0; i < 5; ++i)
b.call();
}
{
A a2;
B b2(bind(&A::call, &a2));
for (int i = 0; i < 5; ++i)
b2.call();
}
return 0;
}
/** Output **
Creating...
Destroying
Destroying
Executing call...
Executing call...
Executing call...
Executing call...
Executing call...
Destroying
Destroying
Creating...
Executing call...
Executing call...
Executing call...
Executing call...
Executing call...
Destroying
*/
When I pass the object with operator () overloaded, there is some multiple calls to destructors; and no objects are being created! So, I can not rely, so to say, on the fidelity of the object state. Does it mean that when I pass a function object (with overloaded operator()) for callback, I should assume that the state of the object is not preserved? And is this, the intended behavior?
On the other hand, callback to a bound member function from inside of an object of another type produces a very stable behavior (I don't know what term to use); i.e. to say, I expected the object state to be preserved; and indeed it is! Is this also an intended behaviour? IOW, is this how functors are generally understood?
PS:
I also checked it with boost::function and boost::bind --- The result is quite the similar. Probably another thread is required to discuss the nuances.
About "no constructors": There are calls to the copy constructor.
Try more instrumenting:
struct A {
A() { std::cout << "Creating..." << "\n"; }
void operator()() { call(); }
A(const A&) { std::cout << "Copying" << "\n"; }
A(A&&) { std::cout << "Moving" << "\n"; } // Assuming C++11
void call() { std::cout << "Executing call..." << "\n"; }
virtual ~A() { std::cout << "Destroying" << "\n"; }
};
About copying:
You hand over the callable by value to B's constructor. It has to be copied.
Bind, it is the intended behavior if you hand in a value. The callable you're handing to bind might be a temporary. Thus, the default behavior is to copy.
You can avoid this, by using a reference wrapper, if you know your callable will survive long enough (as is the case in your code). Try:
int main(int argc, char *argv[])
{
{
A a;
{
B b(a);
}
std::cout << "-------------\n";
B(std::ref(a));
std::cout << "-------------\n";
B(bind(&A::call, a));
std::cout << "-------------\n";
B(bind(&A::call, &a));
std::cout << "-------------\n";
B(bind(&A::call, std::ref(a)));
std::cout << "-------------\n";
}
std::cout << "-------------\n";
return 0;
}
When I pass the object with operator () overloaded, there is some multiple calls to destructors; and no objects are being created!
You are not counting the objects that are constructed using the copy constructor, which is created by the compiler when you don't provide any.
Add a copy constructor to A and you will see the number of calls to the destructor to be the same as the calls to the constructors.
struct A {
A() { std::cout << "Creating..." << "\n"; }
// Add this
A(A const& copy) { std::cout << "Creating..." << "\n"; }
void operator()() { call(); }
void call() { std::cout << "Executing call..." << "\n"; }
virtual ~A() { std::cout << "Destroying" << "\n"; }
};
I am passing unique_ptr to function and then move the pointer to another unique_ptr, all is working fine as need, but while point is unique_ptr does not call destructor of the when it goes out of scope.
Below is my code. and its output, the code is in eclipse.
#include <iostream>
#include <memory>
using namespace std;
class BaseCcExpander;
class DeriveHandler;
class ExpansionRuleExecuter;
class DeriveType1;
class ParamBase
{
public :
ParamBase()
{
std::cout << "Ctor:ParamBase:\n";
}
std::unique_ptr<ExpansionRuleExecuter> paramexpander;
virtual ~ParamBase() { std::cout << "Dtor::~ParamBase:\n"; }
virtual void attachBase(int paramGrp,int paramId,std::unique_ptr<ExpansionRuleExecuter> xbaseExpander);
};
ParamBase* obj;
void ParamBase::attachBase(int paramGrp,int paramId,std::unique_ptr<ExpansionRuleExecuter> xbaseExpander)
{
std::cout << "In: ParamBase::attachHandler :\n";
paramexpander = std::move(xbaseExpander);
}
class ExpansionRuleExecuter
{
public:
ExpansionRuleExecuter()
{
std::cout << "Ctor ExpansionRuleExecuter::ExpansionRuleExecuter:\n" << endl;
}
virtual ~ExpansionRuleExecuter(){
std::cout << "Dtor ~ExpansionRuleExecuter::ExpansionRuleExecuter:\n" << endl;
}
virtual void handleExpansion() = 0;
};
class DeriveHandler : public ExpansionRuleExecuter
{
public:
DeriveHandler()
{
std::cout << "Ctor::DeriveHandler:\n" << endl;
}
~DeriveHandler()
{
std::cout << "Dtor::~DeriveHandler:\n" << endl;
}
void handleExpansion()
{
std::cout << "DeriveHandler expanded\n" << endl;
}
};
ParamBase *obj1;
class BaseCcExpander
{
public:
BaseCcExpander()
{
std::cout << "Ctor::BaseCcExpander:\n" << endl;
}
virtual ~BaseCcExpander()
{
std::cout << "Dtor::~BaseCcExpander:\n" << endl;
}
typedef unique_ptr<ExpansionRuleExecuter> ccHandler;
BaseCcExpander::ccHandler ccBaseHandler;
void attachHandler(int paramGrp, int paramId,std::unique_ptr<ExpansionRuleExecuter> xhandler)
{
std::cout << "BaseCcExpander::attachHandler:\n" << endl;
obj1->attachBase(paramGrp,paramId,std::move(xhandler));
}
};
class DeriveType1 : public ParamBase
{
public :
DeriveType1() { std::cout << "Ctor: DeriveType--------1:\n" << endl;}
~DeriveType1() { std::cout << "Dtor::~DeriveType---------1\n" << endl;}
void attachBase(std::unique_ptr<ExpansionRuleExecuter> xbaseExpander);
};
BaseCcExpander ccexpander;
int main()
{
obj1 = new(DeriveType1);
ccexpander.attachHandler(1,2,std::unique_ptr<ExpansionRuleExecuter>(new DeriveHandler));
if(obj1->paramexpander.get())
{
ExpansionRuleExecuter *expand = obj1->paramexpander.get();
expand->handleExpansion();
}
}
You wrote in a comment:
but by is obj1 not destroying even after the program is over as its in the global space, it should destroy.
There is some misunderstanding here. obj1 is destroyed but the object it points to is not deleted when obj1 is destroyed. If the compiler did that, you won't be able to use:
int main()
{
int i = 10;
int* ip = &i;
// You don't want the run time to call the equivalent of
// delete ip;
// when the function returns. That will lead to undefined behavior
// since ip does not point to memory allocated from the heap.
}
When the program ends, the OS reclaims the memory used by the program but that does not mean that it calls the destructor of obj1.
Had the destructor been responsible for releasing resources other than memory, such as network connections, locks on shared files/folders, etc., they will not be released when the program ends without the destructor getting called.
Your variable pointed by obj1 is not deleted, hence its members would not be destroyed until the delete happens and the unique_ptr will remain alive then the destructor will never be called.
You should either call delete on obj1 at the end of your program or use an unique_ptr on it.
I am trying to learn C++ and from what I've read in books and on SO:
If I use auto x = new Object(); x is a pointer to address of Object and this is in dynamic memory and exists until I delete it.
However if I use Object x; or auto x = Object() it only lasts until it goes out of scope.
In an example they have shown this:
void foo()
{
Point p = Point(0,0);
} // p is now destroyed.
What I don't understand is what happens when I return a object when I don't use new? Will it be a copy of the object?
Here is an example of what I am not sure about:
class Object
{
public:
int X;
static Object Foo(int y)
{
Object result;
result.X = y;
return result;
}
};
class TestContainer
{
public:
void Run()
{
for(auto i = 0; i < 10; i++)
{
_objects.at(i) = Object::Foo(i + (rand() % 10 + 1));
}
}
private:
std::vector<Object> _objects;
};
void main()
{
TestContainer tc;
while(true)
{
tc.Run();
}
}
Note I haven't tested this code but I think it illiterates my confusion. In my main function I instantiate TestContainer and endless call it's Run method. This in turn loops calling a static Foo method on Object that returns a copy of a new Object, which is stored in a vector.
My question is, what happens with all the Object's? If I replace element 2 in the objects vector with a new Object, is the old value now "out of scope" and is deleted?
Will it be a copy of the object?
Yes.
Or a move could be used instead, or the entire thing could be optimised away to produce only one actual object in your final, compiled program.
But, basically, yes.
If I replace element 2 in the objects vector with a new Object, is the old value now "out of scope" and is deleted?
Yes.
As an aside, you're using at on elements that don't exist; to add elements, use insert or push_back.
A simple class like this behaves much like a POD variable. o1=o2 copies the fields, element-wise. So the target Object of an assignment does not get deleted but overwritten.
Objects which go out of scope "go away" (because the stack is unwound) like e.g. an int.
Here is a run-able example that I believe illustrates this behavior:
#include <iostream>
using namespace std;
class Foo {
private:
int id;
public:
Foo(int x)
: id(x)
{
cout << this->id << " is created" << endl;
}
Foo(const Foo& rhs)
: id(rhs.id)
{
cout << "copied " << this->id << endl;
}
Foo& operator=(Foo rhs){
this->id=rhs.id;
cout << "assigned " << this->id << endl;
return *this;
}
~Foo(){
cout << this->id << " is destroyed" << endl;
}
int getID(){
return this->id;
}
};
Foo bar(){
Foo f1 = Foo(1);
cout << f1.getID() << " from bar" << endl;
return f1;
}
int main(){
Foo f2 = bar();
cout << f2.getID() << " from main" << endl;
return 0;
}
This produces this output:
1 is created
1 from bar
1 from main
1 is destroyed
From this, I'm not seeing a copy or an assignment. I suspect what is happening is that both f1 and f2 are referencing the same instance of the object in memory. The object is not being de-allocated when the f1 reference goes out of scope because the object has another reference assigned to it.