GuardianX
GuardianX

Reputation: 512

Mixing vector objects created on heap and on stack

I have a fairly simple question, but cannot wrap my head over it.

Consider I have this code:

#include <iostream>
#include <vector>
using namespace std;

class B
{
public:
    B(const int& val) {this->val = val;}
    int val;
};

class A
{
public:
    A() {}
    void Set(B& ptb)
    {
        ptBs.push_back(&ptb);
    }
    void Set(const int& val)
    {
        ptBs.push_back(new B(val));
    }
    std::vector<B*> ptBs;
};

int main()
{
    A* ptA = new A();
    ptA->Set(B(10));
    ptA->Set(38);

    for (int i=0; i<ptA->ptBs.size(); i++)
        cout << ptA->ptBs[i]->val << endl;

    delete ptA;

    system("pause");
    return 0;
}

The output result is:

10
38

But I think there is memory leak is going on in void Set(const int& val) if I won't call delete with array elements, created by this method.

How can I say, which elements of std::vector have been created on heap so I could free memory in ~A() destructor like this:

~A()
{
    for (int i=0; i<ptBs.size(); i++)
        delete ptBs[i];
}

And do I have to delete vector elements, created via temporary new operation call at all?

Probably I don't see something very simple here, but I really need this functionality in my application.

PS. 10 and 38 are just a simple example. Set function can be called thousands of times with different arguments.

Upvotes: 1

Views: 271

Answers (2)

ecatmur
ecatmur

Reputation: 157414

Fortunately, this line won't compile:

ptA->Set(B(10));

This is because B(10) is a constructor cast expression which creates a prvalue temporary of type B; a prvalue cannot bind to the lvalue reference B & parameter to void A::Set(B& ptb). This is the C++ language protecting you from the consequences of storing a dangling pointer to a temporary value.

It usually makes more sense for A to store its B items by value:

std::vector<B> Bs;

Upvotes: 3

Ivaylo Strandjev
Ivaylo Strandjev

Reputation: 70989

You should decide on whether you give ownership of the object of type B to the instance of A or not. Mixing both will not lead to anything good. Just imagine documenting this class: this class may or may not take ownership to the objects it holds.

Alternative approach that I do not recommend is to create a wrapper to pointers to B, that takes a pointer to B and a boolean flag in it constructor and the boolean flag will indicate if the pointer is to an object allocated on the stack or to an object on the heap.

Upvotes: 2

Related Questions