Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

For a data member, is there any difference between dynamically allocating this variable(or not) if the containing object is already in dynamic memory?

I'm starting with the assumption that, generally, it is a good idea to allocate small objects in the stack, and big objects in dynamic memory. Another assumption is that I'm possibly confused while trying to learn about memory, STL containers and smart pointers.

Consider the following example, where I have an object that is necessarily allocated in the free store through a smart pointer, and I can rely on clients getting said object from a factory, for instance. This object contains some data that is specifically allocated using an STL container, which happens to be a std::vector. In one case, this data vector itself is dynamically allocated using some smart pointer, and in the other situation I just don't use a smart pointer.

Is there any practical difference between design A and design B, described below?

Situation A:

class SomeClass{
public:
    SomeClass(){ /* initialize some potentially big STL container */ }
private:
    std::vector<double> dataVector_;
};

Situation B:

class SomeOtherClass{
public:
    SomeOtherClass() { /* initialize some potentially big STL container,
                        but is it allocated in any different way? */ }
private:
    std::unique_ptr<std::vector<double>> pDataVector_;
};

Some factory functions.

std::unique_ptr<SomeClass> someClassFactory(){
    return std::make_unique<SomeClass>();
}

std::unique_ptr<SomeOtherClass> someOtherClassFactory(){
    return std::make_unique<SomeOtherClass>();
}

Use case:

int main(){
    //in my case I can reliably assume that objects themselves
    //are going to always be allocated in dynamic memory
    auto pSomeClassObject(someClassFactory());
    auto pSomeOtherClassObject(someOtherClassFactory());

    return 0;
}

I would expect that both design choices have the same outcome, but do they? Is there any advantage or disadvantage for choosing A or B? Specifically, should I generally choose design A because it's simpler or are there more considerations? Is B morally wrong because it can dangle for a std::vector?

tl;dr : Is it wrong to have a smart pointer pointing to a STL container?

edit: The related answers pointed to useful additional information for someone as confused as myself. Usage of objects or pointers to objects as class members and memory allocation and Class members that are objects - Pointers or not? C++ And changing some google keywords lead me to When vectors are allocated, do they use memory on the heap or the stack?

like image 688
arthropod Avatar asked May 07 '15 00:05

arthropod


1 Answers

std::unique_ptr<std::vector<double>> is slower, takes more memory, and the only advantage is that it contains an additional possible state: "vector doesn't exist". However, if you care about that state, use boost::optional<std::vector> instead. You should almost never have a heap-allocated container, and definitely never use a unique_ptr. It actually works fine, no "dangling", it's just pointlessly slow.

like image 148
Mooing Duck Avatar answered Nov 15 '22 07:11

Mooing Duck