Question

If I have this two vectors of pointers to MyClass

vector<MyClass*> A;
vector<MyClass*> B;

where A is full and B is empty and I do this operation:

B = A;

Have I to delete the pointers of both vectors or just one?

If I have a dynamic object like this:

MyClass *p = new MyClass;

And this pointer:

MyClass *p2;

If I do this operation:

p2 = p1;

Have I to delete both p and p2 or just one of two?

Was it helpful?

Solution 2

A pointer is just(*1) a regular variable containing an unsigned integer value. This value is an address in memory where the pointed-to-value is stored.

In simpler terms, you can think of a pointer as an array index to memory.

byte ram[16 * 1024 * 1024 * 1024]; // 16Gbs of memory.
size_t index = 10000; // indexes the 10,000th byte of ram.
byte* ptr = ram+ 10000; // ptr contains the same actual value as index
ptr = &ram[10000]; // same value again
ptr = ram;
ptr += 10000; // same value again

When you declare the variable as a pointer, you are extending it's contract within the language. Although, underneath, it is still just a regular variable, the language will treat your interactions with it differently because it is aware that you are expecting to use it to reference memory like this.

So, to answer your original question: You need to match every alloc with a single, corresponding delete. This is a concept called "ownership".

char* a = new char[64];
char* b = a;

Both a and b contain the same value, the address of our 64 bytes, but only one of them "owns" the allocation.

That determination is up to the programmer, and is deterministic: Which pointer will last longest? Which will try to use the pointer last?

char* a = new char[64];
if (a != nullptr)
{
    char* b = a;
    strcpy(b, "hello world");
    // <-- end of b's lifetime.
}
std::cout << a << '\n';

If we deleted b at the end of it's lifetime, a would still point to it. The actual underlying memory is untouched, the problem is that the memory could be allocated to someone else in the mean time. (You forget your watch in the drawer of a hotel. If you go back a week after your stay, will your watch still be in the top drawer?)

In the above example, clearly a is more authoritative for the allocation, so we should delete after a has finished using it.

char* a = new char[64];
if (a != nullptr)
{
    char* b = a;
    strcpy(b, "hello world");
    // <-- end of b's lifetime.
}
std::cout << a << '\n';
delete [] a; // we used new [] match with delete []

Pointer management can easily be difficult, and has been causing bugs in C code since C existed.

C++ provides several classes that encapsulate the properties of ownership. std::unique_ptr is a single point of ownership for allocations ideal for when you have a container of pointers.

std::vector<std::unique_ptr<YourClass>> myVector;
myVector.emplace_back(new YourClass));

when this vector goes out of scope, the unique_ptr objects will go out of scope, at which point they will delete their allocations. Problem solved.

There is also std::shared_ptr if you may need the ownership to be dynamic...

std::vector<std::shared_ptr<MailItem>> inbox;
std::set<std::shared_ptr<MailItem>> urgent;

// incoming mail goes into inbox, copied to urgent if its a priority...

for (auto it : inbox)
{
    if (it->>IsPriority()) {
        urgent.insert(it);
        // now there are TWO pointers to the same item.
    }
}

In the above case, the user can delete an urgent item from inbox but the item still exists. shared_ptr uses a "reference counter" to know how many pointers own the object. In most cases, this is going to be more complex than you need and unique_ptr will be sufficient.

(*1 There are some platforms where pointers are more than just a single variable but that's kind of advanced and you probably don't need to worry about that until such time as you work on such a platform)

OTHER TIPS

The pointers are pointing to the same piece of memory, so you only need to delete it once.

You get undefined behaviour if you try to delete an object through a pointer more than once.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top