0

Suppose I need to create a heap allocated container from another container. Does the initial container need to be also heap-allocated, or are its values implicitly copied into the heap, and hence the original container can just be a local variable? Example:

list<int> my_function()
{
    set<int> my_set;
    my_set.insert(1);
    my_set.insert(2);

    list<int> *my_list = new list<int>(my_set.begin(), my_set.end());

    return *my_list;
}

versus

list<int> my_function()
{
    set<int> *my_set = new set<int>;
    my_set->insert(1);
    my_set->insert(2);

    list<int> *my_list = new list<int>(my_set->begin(), my_set->end());

    return *my_list;
}

Which of the above is correct? I want to avoid duplicating heap-memory without my knowledge, of course.

Andrew Martin
  • 303
  • 1
  • 2
  • 12

1 Answers1

2

This would be correct:

list<int> my_function()
{
    set<int> my_set;
    my_set.insert(1);
    my_set.insert(2);   
    return list<int>(my_set.begin(), my_set.end());
}

I am not sure what you mean with "heap allocated", but keep in mind, that list and set already store data on the heap.

Danvil
  • 22,240
  • 19
  • 65
  • 88
  • Thanks for the quick response. I'm fairly new to C++ - do object constructors implicitly use new? I'm confused because it just looks like it would be returning a local variable, unless a constructor called with the return keyword increases the scope of the object. – Andrew Martin Apr 05 '14 at 01:42
  • STL containers need to allocate data to store the elements you add. The memory for this is allocated on the heap. Thus if you write `set my_set;` most of the data is already stored on the heap. – Danvil Apr 05 '14 at 01:44
  • If you write `A foo() { A a; return a; }` then it returns a copy. For STL containers this can be optimized. If you want to be dead sure that no unnecessary copying is going on you can use pointers. But then you have to take care of calling delete or using `shared_ptr`. – Danvil Apr 05 '14 at 01:48
  • Ah very true, thanks! That makes perfect sense why I don't need to create my set with new. Just as a final clarification, does this mean the list constructor used in this fashion uses the same copy of the elements in the set? i.e. in your code, after the function returns would the list have the same pointers as the set or would they be copies? Otherwise I can see issues with being unable to free the set later on. – Andrew Martin Apr 05 '14 at 01:50
  • If my above comment is unclear, here's what I'm getting at: using your exact code example, could I later on delete the list and be sure that the set is also gone as well? No leaks? – Andrew Martin Apr 05 '14 at 01:53
  • For my code example, there is not need to call delete. STL containers take care of themselves. You only need to call delete if you have created an object with new. And you can only call delete with a pointer... – Danvil Apr 05 '14 at 01:54
  • Wow, that's a really nice feature of STL containers. Thanks for all your help! If you don't mind me asking since the question has already been answered, how does this work internally? When exactly is the storage freed? If I only need an STL container for part of my application's runtime, is it possible to explicitly free it when I'm finished with it? As far as I know there is no garbage collector in C++ but I could be totally wrong. – Andrew Martin Apr 05 '14 at 02:03
  • It is freed when it goes out of scope. See also here http://stackoverflow.com/questions/10080935/when-is-an-object-out-of-scope – Danvil Apr 05 '14 at 02:29