I am trying to make a deep copy of the object but for some reason I keep getting an error thrown at me.
Invalid address specified to RtlValidateHeap( 000002081EF60000, 000002081EF755C0 )
What does this mean? I have commented out the last two lines as this is not what causes the error but is what I would like to achieve.
#include "pch.h"
#include <iostream>
class Constant
{
public:
int Value;
Constant(int value) {
Value = value;
}
void set_value(int new_value) {
Value = new_value;
}
int get_value() {
return Value;
}
};
int main() {
std::shared_ptr<Constant> foo = std::make_shared<Constant>(1);
std::shared_ptr<Constant> bar(foo.get());
//bar->set_value(4);
//std::cout << (foo->get_value()) << " should be differnt than " << (bar->get_value());
return 0;
}
I expect the output "1 should be different from 4".
You are getting heap corruption due to a double-free problem. Your second shared_ptr is constructed with a raw pointer, which is already managed by the first shared_ptr. So both try to manage the same object, which leads to a double-free at the end of the scope.
To make a copy of an object in C++, just use copy construction:
#include "pch.h"
#include <iostream>
class Constant
{
public:
int Value;
Constant(int value) {
Value = value;
}
void set_value(int new_value) {
Value = new_value;
}
int get_value() {
return Value;
}
};
int main() {
Constant foo(1);
Constant bar(foo); // copy-construction
bar.set_value(4);
std::cout << (foo.get_value()) << " should be differnt than " << (bar.get_value());
return 0;
}
Note: in this example it is sufficient to rely on the default compiler-generated copy constructor.
Phil1970 got it right in the comments.
#include "pch.h"
#include <iostream>
class Constant
{
public:
int Value;
Constant(int value) {
Value = value;
}
void set_value(int new_value) {
Value = new_value;
}
int get_value() {
return Value;
}
};
int main() {
std::shared_ptr<Constant> foo = std::make_shared<Constant>(1);
std::shared_ptr<Constant> bar = std::make_shared<Constant>(*foo);
bar->set_value(4);
std::cout << (foo->get_value()) << " should be differnt than " << (bar->get_value());
return 0;
}
His solution allows you to use shared pointers and still obtain the desired result. Thanks Phil!
When you call this function:
std::shared_ptr<Constant> bar(foo.get());
You are directly taking the data pointer of the ptr internal and adding an additional controller(bar) to it. So don't pass the data ptr instead of the share ptr itself to the constructor.It should be like:
std::shared_ptr<Constant> bar(foo);
Related
I really didn't know what to put as the title for this so ignore that. I also don't know how to describe the question so here is my issue.
#include <iostream>
#include <vector>
class ClassB {
public:
//LOOK AT THIS PART
int value;
char letter;
ClassB(char t, int v) {
letter = t;
value = v;
}
};
class ClassA {
private:
ClassB* ptr;
public:
ClassA(ClassB n) {
ptr = &n;
}
ClassB* getPtr(){
return ptr;
}
};
int main() {
std::vector<ClassA> objects;
for(int i=0;i<4;i++) {
objects.push_back(ClassA(ClassB('a',i)));
}
std::cout << "Value: " << objects[1].getPtr()->value << std::endl;
std::cout << "Letter: " << objects[1].getPtr()->letter;
return 0;
}
In this code, the output I should receive is
Value: 1
Letter: a
However I am receiving this
Value: 1
Letter
Also, if I were to declare letter before value (look at the comment in code), then the output would say
Value: 0
Letter: ☺
I'm not sure why the order I declare them in would affect anything, or why I'm getting a smiley face instead of a. Any help is appreciated, thank you!
The problem lies here:
ClassA(ClassB n) {
ptr = &n;
}
ClassB is a temporary variable that gets destructed at the end of the function. The pointer becomes invalid and the program goes nuts.
A simple and safe way to go about this, is to use an std::unique_ptr and pass parameters. unique_ptr will automatically delete ClassB when ClassA is deleted:
private:
std::unique_ptr<ClassB> ptr;
public:
ClassA(char t, int v) {
ptr = std::make_unique<ClassB>(t, v);
}
There's also just keeping a value instead of a pointer.
I want to seek help on this issue I encountered when learning C++. I tried to store objects into an array directly, but realize the objects gets deconstructed right away. I could not figure out why exactly is this so.
#include <iostream>
class Thing{
public:
~Thing(){
std::cout<<"Thing destructing";
}
};
int main(){
Thing arr[1];
arr[0] = Thing();
int x;
std::cin>>x;
};
In this statement
arr[0] = Thing();
there is used the default copy assignment operator that assigns the temporary object created by this expression Thing() to the element of the array. After the assignment the temporary object is destroyed.
To make it more clear run this demonstration program.
#include <iostream>
class Thing
{
public:
~Thing()
{
std::cout<<"Thing " << i << " destructing\n";
}
Thing & operator =( const Thing & )
{
std::cout << "Thing " << i << " assigning\n";
return *this;
}
Thing() : i( ++n )
{
std::cout << "Thing " << i << " constructing\n";
}
private:
size_t i;
static size_t n;
};
size_t Thing::n = 0;
int main()
{
{
Thing arr[1];
arr[0] = Thing();
}
std::cin.get();
return 0;
}
Its output is
Thing 1 constructing
Thing 2 constructing
Thing 1 assigning
Thing 2 destructing
Thing 1 destructing
Assuming you don't know already.
Smart-Pointer
#include <memory>
// ...
int main() {
std::shared_ptr<Thing> arr[1];
arr[0] = std::shared_ptr<Thing>(new Thing());
// ...
// <-- Is automatically deleted around here.
}
Pointer
Not-Recommended;
Using pointer would look like:
int main() {
Thing *arr[1] = {};
arr[0] = new Thing();
int x;
std::cin >> x;
// WARNING: remember to manually delete.
delete arr[0];
} // <-- BTW, you don't need semi-colon.
Flex Ferrum post a code sample here (I think it is Minimal, Complete, and Verifiable enough):
#include <iostream>
#include <functional>
using namespace std;
class Bang
{
public:
Bang(int i = 0) : m_val(i)
{
m_foo = [this] {std::cout << m_val << std::endl;};
}
~Bang()
{
m_val = -1;
}
void Foo()
{
m_foo();
}
private:
int m_val;
std::function<void ()> m_foo;
};
Bang GetBang()
{
return Bang(100500);
}
int main() {
Bang b(100500);
b.Foo();
b = GetBang();
b.Foo();
return 0;
}
Our nice Flex also offer a live demo
After a rough look, I thought it will output 100500, but the real output is:
-1
Why? What's behind it?
How to fix it?(output 100500, not -1)
I have written some my own reasonings in the ask box, but found it is more fit to be posted as an answer(will make the question too long). If my answer is wrong, please correct it and more answers are welcome
Ah, it should blame the destructor of temporary - Bang(100500), which returns form GetBang, is prvalue, and has temporary object lifetime.
[this] will be stored as reference of *this, like this:
class Lambda
{
public:
void operator()() const
{
//output
}
private:
Bang& bang;
public:
Lambda(Bang& bang) : bang{bang}
{
}
} lambda{*this};
...
m_foo = lambda;
Because here is no RVO, so, the temporary Bang(100500) will first be assigned to b, then be destroyed.
Custorm operator(), constructor, and destructor to output some information:
#include <iostream>
#include <functional>
using namespace std;
class Bang
{
public:
Bang(int i = 0) : m_val(i)
{
std::cout << "Bang(int i = 0) m_val address is " << &m_val << '\n';
class Lambda
{
public:
void operator()() const
{
std::cout << "operator() m_val address is " << &bang.m_val << '\n';
std::cout << bang.m_val << std::endl;
}
private:
Bang &bang;
public:
Lambda(Bang &bang) : bang{bang}
{
}
} lambda{*this};
m_foo = lambda;
}
~Bang()
{
std::cout << "~Bang()\n";
m_val = -1;
}
void Foo()
{
m_foo();
}
private:
int m_val;
std::function<void()> m_foo;
};
Bang GetBang()
{
return Bang(100500);
}
int main()
{
Bang b;
b = GetBang();
b.Foo();
return 0;
}
live demo
Output:
Bang(int i = 0) m_val address is 0x7ffd202c48b0
Bang(int i = 0) m_val address is 0x7ffd202c48e0
~Bang()
operator() m_val address is 0x7ffd202c48e0
-1
~Bang()
shows:
dtor will be called before output, That means that the temporary object has been destroyed.
m_value's address doesn't change.
The two guaranteed we still access the temporary's m_value from the b's m_foo().
It should be Undefined Behaviour to access an object which has be destroyed, but no warning and errors required.
Update
To solve the problem, there two solutions:
Like #Killzone Kid points out, capture with an initializer: [bang = *this]. This requires c++14.
More simpler way to capture of the current object by-copy: [*this]. This requires c++17. live demo
You probably want to pass current object to lambda by value *this so that it can be stored and copied when you copy assign Bang. Passing pointer this will store and copy pointer to the temp object that has been destroyed when you copy assign Bang.
This works as it should:
#include <iostream>
#include <functional>
class Bang
{
public:
Bang(int i = 0) : m_val(i)
{
m_foo = [bang = *this] { std::cout << bang.m_val << std::endl; };
}
~Bang()
{
m_val = -1;
}
void Foo()
{
m_foo();
}
private:
int m_val;
std::function<void()> m_foo;
};
Bang GetBang()
{
return Bang(100500);
}
int main()
{
Bang b;
b = GetBang();
b.Foo();
return 0;
}
Demo: https://ideone.com/LUDrBb
This is a standard pimpl in VS 2013:
.h:
#pragma once
#include<string>
#include<iostream>
#include <memory>
class TestClass01
{
private:
class impl;
std::unique_ptr<impl> pimpl;
public:
TestClass01();
TestClass01(int num, std::string str);
TestClass01(int num);
TestClass01(std::string str);
virtual ~TestClass01();
int ReturnMyInt();
std::string ReturnMyString();
};
.cpp
#include "stdafx.h"
#include "TestClass01.h"
#include <iostream>
class TestClass01::impl
{
public:
int myint;
std::string mystr;
};
TestClass01::TestClass01()
{
pimpl = std::make_unique<impl>();
}
TestClass01::TestClass01(int num, std::string str)
{
//pimpl = std::make_unique<impl>();
TestClass01();
pimpl->myint = num;
pimpl->mystr = str;
}
TestClass01::TestClass01(int num)
{
TestClass01();
pimpl->myint = num;
}
TestClass01::TestClass01(std::string str)
{
TestClass01();
pimpl->mystr = str;
}
TestClass01::~TestClass01()
{
std::cout << "Destroyed TestClass01 with int=" << pimpl->myint << " and str=" << pimpl->mystr;
}
int TestClass01::ReturnMyInt()
{
return pimpl->myint;
}
std::string TestClass01::ReturnMyString()
{
return pimpl->mystr;
}
The problem with this code is that it crashes if I call the default constructor from any other constructor instead of directly instanciating impl:
TestClass01::TestClass01(int num, std::string str)
{
//pimpl = std::make_unique<impl>(); -> This works, the line below doesn't
TestClass01();
pimpl->myint = num;
pimpl->mystr = str;
}
In the line below TestClass01(); pimpl is empty. But setting a breakpoint in the default constructor reveals that pimpl points to an object in the default constructor, becoming empty only when it leaves it.
What's causing pimpl to become empty? It's a member variable and it shouldn't get out of scope (and therefore cause unique_ptr to delete the containing object).
The proper syntax for constructor delegation in C++11 is
TestClass01::TestClass01(int num) : TestClass01() // <-- here, in the ctor
{ // init list.
pimpl->myint = num;
}
VS 2013 supports that, so this should work for you. The way you're doing it now just creates a nameless temporary TestClass01 object that's immediately destroyed and doesn't affect the current *this at all.
You can't call a constructor directly. When you try, all you're doing is creating an unnamed temporary that disappears after the call, and it doesn't affect the current object at all.
Here's some code that demonstrates it:
struct test
{
test() { cout << "default constructor on " << this << endl; }
test(int) { cout << "int constructor on " << this << endl; test(); }
};
int main() {
test t(1);
cout << "test object at " << &t << endl;
return 0;
}
See a demo at http://ideone.com/n2Thrn. The object pointers are output, notice that they're different.
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.