Pergunta

I'm trying to clear up my understanding of some memory issues in C++, primarily with containers containing pointers. Say I have something like this:

Header.H

#ifndef test_Header_h
#define test_Header_h

#include <vector>

using std::vector;

class ClassA {
    int* intPtr;

public:
    ClassA(int n);
    ~ClassA();
};

class ClassB {
    vector<ClassA*> vecPtr;

public:
    ClassB();
    ~ClassB();

    void someFunc();
};

#endif

main.cpp

#include <iostream>
#include "Header.h"

int main(int argc, const char * argv[])
{
    ClassA objA(5);
    ClassB objB;

    return 0;
}

ClassA::ClassA(int n) {
    intPtr = new int[n];
}
ClassA::~ClassA() {
    delete intPtr;
}

ClassB::ClassB() {
    vecPtr = vector<ClassA*>(0);
}

ClassB::~ClassB() {
    //no destructor needed
}

void ClassB::someFunc() {
    //vecPtr = something using new;
    int* testPtr = new int[vecPtr.size()];
    //do stuff
    delete testPtr;
}

Does vecPtr ever need to be deleted? Or does the destructor of ClassA accomplish this for me? Also, if instead of having a vector, would it be the same situation if I had used a list of pointers or a pair? Finally, for clarification testPtr needs to be deleted in someFunc because that is the scope it was declared in, so putting it in the destructor would be pointless. If testPtr shared the address the address of an important member, deleting it would also the important member? I know there is quite a few questions but I think I'm just going around in a circular argument in my head, confusing myself more and more.

Foi útil?

Solução

vecPtr does not need to be deleted, because it is not a pointer. This might be different for the pointers in vecPtr and depends on who has the ownership for those pointers.

Yes, testPtr must be deleted, where it is available. Anything else won't even compile. If you point testPtr to a member and delete that, you will likely see a double free or corruption error when the member would be deleted on the destructor.

In general where something must be deleted is up to the implementation. The only thing that you need to look out for is that every new gets exactly one delete from somewhere in any code path. Usually constructors/destructor are therefore a good place.

Outras dicas

You have big problems here. Remember this:

1) any new must be balanced with a delete.

2) any new[] must be balanced with a delete[].

In fact, if you mix them (as you've done), you have undefined behaviour. Boom! You need to write delete[] intPtr; and delete[] testPtr;

Also and simply put, you don't write delete vecPtr since you didn't write new vecPtr.

Internally, the C++ runtime remembers the number of elements that you've allocated using new[]. You need to use delete[] to allow that runtime to access that information.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top