I know it should be a trivial question but need to find out why.
The following code compiled by failed with
a.out(93143) malloc: *** error for object 0x7fff5af8293f: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
codes:
#include <iostream>
using namespace std;
class A
{
};
class B
{
private:
A a;
public:
B(){a=*new A();}
~B(){delete &a;}
};
int main()
{
B b;
}
According to the immediate comments, I realized that the dynamically allocated object in "new" immediately lost its owner after assigning to "a". Now if I do want an object instead of a pointer to "A", what is the best solution?
Because your member variable is not a pointer. You're not storing the dynamically allocated object you're assigning a copy of it to A a; and leaking the dynamically allocated one.
Change class B to:
class B
{
private:
A* a;
public:
B(){a= new A();}
~B(){delete a;}
};
or better yet
class B
{
private:
A a;
public:
B() {}
~B(){}
};
In case you really need a dynamically allocated object, I would like to propose this final solution using smart pointers (you'll need C++11 or boost for this):
#include <memory>
#include <iostream>
class A
{
public:
A() { std::cout << "Hi" << std::endl; }
~A() { std::cout << "Bye" << std::endl; }
};
class B
{
public:
B(): a(new A()) {};
//~B() {} <-- destructor is no longer needed, the unique_ptr will delete the object for us
private:
std::unique_ptr<A> a;
};
int main(int argc, char* argv[])
{
B b;
}
You can see that the constructor and destructor for A is called here.
Related
I want to call the child's function from parent's function in reinterpreted class, like below.
Example
#include <iostream>
class A {
public:
void func1() {
// some code
func2();
// some code
}
protected:
virtual void func2() {
printf("class A\n");
}
};
class B : public A {
protected:
virtual void func2() {
printf("class B\n");
}
};
int main() {
A* ab = new A();
ab->func1(); // this print "class A"
B* bab = reinterpret_cast<B*>(ab);
bab->func1(); // this also print "class A"
// I want to print "class B" when I use bab->func1()
}
In this situation, Is there any way to print class B using the reinterpreted class bab without redefining func1?
For C++ polymorphism to kick in, you must create an instance of the derived class somewhere, but you can store a pointer to the base class. Using the base-class pointer will dispatch to the overridden functions of the derived class. So your definition of A and B is fine, your usage in the main function is not. reinterpret_cast is not intended for this.
#include <iostream>
#include <memory>
class A {
public:
void func1() {
// some code
func2();
// some code
}
protected:
virtual void func2() {
printf("class A\n");
}
};
class B : public A {
protected:
virtual void func2() {
printf("class B\n");
}
};
int main() {
{
// This works, but don't do this. Naked "new" is not modern C++ and dangerous.
A* ab = new B();
ab->func1();
delete ab;
}
{
// VARIANT 2: use smart pointers
std::unique_ptr<A> ab = std::make_unique<B>();
ab->func1();
}
{
// VARIANT 3: A non-smart pointer is okay, as long as it
// 1. references an existing allocated object
// 2. the pointer does not outlive the object it points to
B b;
A* ab = &b;
ab->func1();
}
{
// VARIANT 4: Like Variant 3, but with reference instead of pointer
B b;
A& ab = b;
ab.func1();
}
}
Output
class B
class B
class B
class B
https://godbolt.org/z/8e5E85nx5
EDIT: Try to avoid allocation with new. Any memory allocated in this fashion must be freed by you using delete and it is very easy to forget (I did when I first wrote this answer, kinda proving my point). Even if you do delete the memory at the end of your function, there is the possibility that your code never reaches this statement, e.g. if exceptions are thrown somewhere between new and delete.Here is some further reading:
Why is it a bad idea to use 'new'?
Why should C++ programmers minimize use of 'new'?
I'm trying to pass a callback to a member in one of my classes. The member is held in a shared_ptr because class A is not the only owner.
#include <iostream>
#include <functional>
#include <memory>
class B {
public:
void update() {
cb(5);
}
void set_callback(std::function<void(int)> callback) {
cb = callback; // exception thrown here
}
private:
std::function<void(int)> cb;
};
class A {
public:
A() : b() {
b->set_callback([](int x) {
std::cout << x << std::endl;
});
}
void update() {
b->update();
}
private:
std::shared_ptr<B> b; // seemingly the culprit
};
int main()
{
A a;
a.update();
}
This program should print 5, but I get an read access violation from inside the "functional" STL header. Here are screenshots of the exception and call stack. In the code, changing std::shared_ptr<B> to B fixes the read access violation. What am I doing wrong?
b doesn't point to anything. A() : b() {...} just initializes the shared_ptr instance. You have to allocate a B with make_shared:
A() : b(std::make_shared<B>()) { ... }
But from this code we can see there's really no reason to use a pointer. A B instance on the stack would do just fine.
A.hh
#ifndef A_HH
#define A_HH
#include <iostream>
#include <string>
using namespace std;
class A {
private:
int size;
string name;
public:
A();
~A();
int Load(int, string);
int getSize();
string getName();
/* data */
};
#endif
A.cc:
#include "A.hh"
A::A() {
}
int A::Load(int _size, string _name) {
size = _size;
name = _name;
return 0;
}
int A::getSize() {
return size;
}
string A::getName() {
return name;
}
A::~A() {
}
B.hh:
#ifndef B_HH
#define B_HH
#include "A.hh"
#include <string>
class B {
private:
A* objectA;
public:
B();
B(A*);
~B();
A* getA();
/* data */
};
#endif
B.cc:
#include "B.hh"
B::B() {
}
B::B(A* obj) {
objectA = obj;
}
A* B::getA() {
return objectA;
}
B::~B() {
}
C.cc
#include "C.hh"
C::C() {
}
int C::doSomething() {
cout<<"size = "<<getA()->getSize()<<endl;
cout<<"name = "<<getA()->getName()<<endl;
return 0;
}
C::~C(){
}
C.hh
#ifndef C_HH
#define C_HH
#include "B.hh"
class C : public B {
public:
C();
~C();
int doSomething();
/* data */
};
#endif
main.cc
#include "A.hh"
#include "B.hh"
#include "C.hh"
int main() {
A* objA = new A();
objA->Load(1, "Hello Drew Dormann :)");
B* objB = new B(objA);
C* objC = new C();
objC->doSomething();
return 0;
}
Why am I getting a segfault on doSomething()?
I'm using the child of B to handle the object parsed into B. Also I have to use B's child to handle A because this is part of something much bigger and this is the only way to simplify it.
I don't understand why this happens.
There seems to be a misconception of how objects work and are constructed behind this question.
C* objC = new C();
Creates brand new C. The C constructor does absolutely nothing beyond allocating storage, so absolutely nothing is initialized. Because C inherits from B, C's constructor will call the default constructor for B, which does nothing, but calls the default constructor for its parent, A.
A's default constuctor does not initialize name and size so their values are undefined. B's default constuctor does not initialize objectA so it is undefined, leading to the segfault.
This C was created by new comes out of some pool of memory, typically the heap, and needs to be returned to this pool with delete when no longer needed. If it is not the program will lose the memory used by C.
The same sample can be performed without dynamic allocation.
C objC;
Creates a C, but does it on the stack. When the stack unrolls at the end of the function or code block (search term: variable scope) the C will be popped off and automatically destroyed. This is typically the better way to operate as it requires no additional memory management. The C looks after itsef and can be considered "fire-and-forget."
Back on topic...
objC->doSomething();
Do something calls the getA method inherited from B which dutifully returns the uninitialized objectA. objectAis promptly used to call getSize with objectA as the concealed this parameter. Since Crom only knows what objectA is actually pointing at it would be a minor miracle if this->size wasn't somewhere crash-provoking.
If the OP expects
A* objA = new A();
objA->Load(1, "Hello Drew Dormann :)");
and
B* objB = new B(objA);
to have some bearing on the state of C. The OP is incorrect. objA and objB are their own entities. They are different objects and every object has its own state.
In order to have C initialize B with something other than the default constructor, you need your C constructor to look more like this:
C::C(A* obj) : B(obj)
{
}
This assigns a pointer to A passed into C to B, using B's B(A*); constructor.
C::C(A* obj,
int size,
string name) : B(obj, size, name)
{
}
B::B(A* obj,
int size,
string name) : A(size, name)
{
}
Cascades all of the parameters needed to fully specify a C all the way down to A.
As B needs to have objectA initialized, I recommend removing B and C's default constructors to force initialization to a meaningful value. If B and C require default constructors for some other purpose, such as storage in a standard container, either getA() needs to be a lot smarter or B's default constructor must initialize objectA to some safe value.
This still leaves the great question of why B contains a pointer to a parent. I'll leave that to the OP to work out.
And while The OP is at it, I recommend reading this: What is The Rule of Three?. Because the next question is likely to be "Dude! Who deleted my objectA"?
Also using namespace std in a header is very super bad. Read here: Why is "using namespace std" considered bad practice?
Your problem is that objectA in objC points to invalid memory hence in doSomething() you are trying to call the member access operator on an invalid pointer. You can change the default constructor of B to construct an object and have objectA point to it, make sure to free your memory as well!
#include <iostream>
#include <string>
/*#################
// !! class A !! //
#################*/
class A
{
private:
int size = 0;
std::string name;
public:
int Load(int, const std::string&);
int getSize() { return size; }
std::string getName() { return name; }
};
int A::Load(int _size, const std::string &_name)
{
size = _size;
name = _name;
return 0;
}
/*#################
// !! class B !! //
#################*/
class B
{
private:
A* objectA;
public:
B() : objectA(new A()) { }
B(A* obj) : objectA(new A(*obj)) { }
A* getA() { return objectA; }
virtual ~B() { delete objectA; }
};
/*#################
// !! class C !! //
#################*/
class C : public B
{
public:
C() = default;
int doSomething();
};
int C::doSomething()
{
// Problem: objectA points to invalid memory
std::cout << "size = " << getA()->getSize() << std::endl;
std::cout << "name = " << getA()->getName() << std::endl;
return 0;
}
/*#################
// !!! main !!! //
#################*/
int main()
{
A* objA = new A();
objA->Load(1, "Hello Drew Dormann :)");
B* objB = new B(objA);
C* objC = new C();
objC->doSomething();
// free your memory!!!
delete objA;
delete objB;
delete objC;
return 0;
}
I have this:
#include <iostream>
#include <vector>
class B
{
public:
std::string s;
B()
{
std::cout<<"constructing B"<<std::endl;
}
~B()
{
std::cout<<"destroying B"<<std::endl;
}
};
class A
{
private:
void Do(std::vector<B>& v)
{
B b;
b.s = "this is a test";
v.push_back(b);
}
public:
void Check()
{
std::vector<B> v;
Do(v);
std::cout<<v[0].s<<std::endl;
}
};
int main()
{
A a;
a.Check();
}
Question: this worked, so apparently compiler knew that b should not go out of scope, but is this a good way to populate vector v with objects created inside Do?
The output of the above is
constructing B
destroying B
this is a test
destroying B
Is this correct to assume that b was copied, then older value was destroyed and newer passed in vector?
The vector stores a copy of local object b. So there is no problem with the code relative to this local variable
push_back copied b into a new element created for v, then b was destroyed before Do returned.
I have a base class, and some polymorphs of it. I want to be able to create an object of type class base, and then morph it to class derived, and back to base. Can one do this? I am doing it as follows, but I am not sure this is the right approach:
Assuming I have these classes:
class base {
public:
int var;
base();
virtual ~base();
virtual void func1();
void func2();
}
class derived1 : base {
public:
unique_ptr<otherClass> otherVar;
vector<unique_ptr<anotherClass>> myVec;
derived1();
~ derived1() {
otherVar.reset();
for (unsigned int i=0; i< myVec.size(); i++) {
myVec[i].reset();
}
myVec.clear();
vector<unique_ptr< anotherClass >>().swap(myVec);
}
void func1(){
//do something
}
}
class derived2 : base {
public:
derived2();
~ derived2();
void func1(){
//do something else
}
}
Now somewhere else in code I do this:
unique_ptr<base> myObject;
myObject = unique_ptr< derived1 > (new derived1());
If later I do this:
myObject.reset();
myObject = unique_ptr< base > (new base());
the heap memory increases significantly. What is the reason, and how can one avoid this problem?
Edit1
I added more detail to derived1.
I get no errors, and the program runs without problem, only memory goes up when myObject morphs.
BTW, myObject never goes out of scope, it only changes its shape (so I am not actually sure that I am using the right kind of pointer).
Edit2
I managed to get rid of most of the pointers inside classes (unfortunately I can't use normal variables in all cases), and now I have very little memory growth.
But my understanding was that use of smart pointers should make life easier not harder. Is there any kind of pointer in C++ that we can use, free the memory without deleting it (I thought reset() is supposed to do that) and then reassign some other value to it later?
I must say though, for simple object this can be done by unique_ptr, but for complicated classes (that have pointers to other classes as their member variables), it seems that some of the memory never gets freed even after calling reset().
Edit3
I found out that the problem was not with the C++ part of the code, but with the OpenGL part. Sorry for confusing experts here XD.
While I was doing this:
otherVar.reset();
this otherVar contained OpenGL textures. The destructor of this object was supposed to delete all the textures at once (on the Mac at least) with this call:
glDeleteTextures(textureCount, textures);
but on iOS (OpenGL ES), I had to delete the textures individually, like so:
glDeleteTextures(1, &tex.textureID);
Still, I have no idea why glDeleteTextures(textureCount, textures) doesn't delete all the textures at once in the iOS app, but at least I found a kind of workaround for it.
Thanks everybody.
It is impossible to be sure, but I suspect there may be a cyclic ownership pattern in your code. Here is what that looks like in a simple example:
#include <iostream>
#include <memory>
struct B;
struct C;
struct A
{
std::unique_ptr<B> b_ptr_;
~A();
};
struct B
{
std::unique_ptr<C> c_ptr_;
~B();
};
struct C
{
std::unique_ptr<A> a_ptr_;
~C();
};
A::~A()
{
std::cout << "~A()\n";
}
B::~B()
{
std::cout << "~B()\n";
}
C::~C()
{
std::cout << "~C()\n";
}
int
main()
{
std::unique_ptr<A> a_ptr(new A);
a_ptr->b_ptr_ = std::unique_ptr<B>(new B);
a_ptr->b_ptr_->c_ptr_ = std::unique_ptr<C>(new C);
a_ptr->b_ptr_->c_ptr_->a_ptr_ = std::move(a_ptr);
}
When compiled and run, this program has no output. That is worrisome as the destructors for A, B and C are not run, indicating a memory leak.
There are many ways to fix cyclic ownership. But the first step is in understanding your memory ownership graph, and assuring that it is acyclic, and with unique_ptr, one must also assure that any node in the graph has only one (owning) parent node.
Here is one way to break the ownership cycle for this example:
#include <iostream>
#include <memory>
struct B;
struct C;
struct A
{
std::unique_ptr<B> b_ptr_;
~A();
};
struct B
{
std::unique_ptr<C> c_ptr_;
~B();
};
struct C
{
A* a_ptr_;
~C();
};
A::~A()
{
std::cout << "~A()\n";
}
B::~B()
{
std::cout << "~B()\n";
}
C::~C()
{
std::cout << "~C()\n";
}
int
main()
{
std::unique_ptr<A> a_ptr(new A);
a_ptr->b_ptr_ = std::unique_ptr<B>(new B);
a_ptr->b_ptr_->c_ptr_ = std::unique_ptr<C>(new C);
a_ptr->b_ptr_->c_ptr_->a_ptr_ = a_ptr.get();
}
which correctly outputs:
~A()
~B()
~C()
I.e. insert a non-owning "raw pointer" into the cycle. One could also use shared_ptr and weak_ptr to break the cycle:
#include <iostream>
#include <memory>
struct B;
struct C;
struct A
{
std::shared_ptr<B> b_ptr_;
~A();
};
struct B
{
std::shared_ptr<C> c_ptr_;
~B();
};
struct C
{
std::weak_ptr<A> a_ptr_;
~C();
};
A::~A()
{
std::cout << "~A()\n";
}
B::~B()
{
std::cout << "~B()\n";
}
C::~C()
{
std::cout << "~C()\n";
}
int
main()
{
std::shared_ptr<A> a_ptr(new A);
a_ptr->b_ptr_ = std::shared_ptr<B>(new B);
a_ptr->b_ptr_->c_ptr_ = std::shared_ptr<C>(new C);
a_ptr->b_ptr_->c_ptr_->a_ptr_ = std::move(a_ptr);
}
~A()
~B()
~C()
Should I be mistaken that cyclic ownership is the culprit in your case, your time will not be completely wasted by reviewing, understanding and documenting the ownership paths in your code.