Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

does push_back() "new" an object before to add to the std::list in c++

Tags:

c++

gcc

c++11

stl

I am new to c++ standard library. I want use std::list. I know if I create a list by myself instead of using stl, I should allocate memory to a new object, and then add it to the list.

a c-style list of class A:

A *ptrA = new A();     
ptrA->setElement(value);
ptrA->next = null;
currentPositionMyCstyleList->next = ptrA;
ptrA->prev = currentPositionMyCstyleList;

If I using stl, is it necessity to "new" an object? Does push_back() "new" an object before to add to the std::list in c++?

Does Code below correct?

A aObj(value);     
listA.push_back(aObj); // Will push_back() "new" an object and copy the value of aObject to the object before add it to list

Will the value of aObj be released in code below:

funcAddToList() {
    A aObj(value);     
    listA.push_back(aObj);
}
funcDispList() {
    // display listA  // Does the value of aObj still in list?
}

What does push_back() actually do?

I still confuse after reading stl_list.h_push_back() , _M_insert, _M_create_node

Thanks for your time.

like image 295
Nick Dong Avatar asked Feb 05 '16 10:02

Nick Dong


4 Answers

The push_back method from std::list will copy or move your argument.

Internally, it is up to the implementation to deal how it wants to manage the object.

like image 145
dkg Avatar answered Sep 23 '22 03:09

dkg


In all likelihood...

The list has an allocator. The default allocator simply calls through to new (as you'd expect). You can provide an alternate allocator if that suits.

Since you're using C++11 you might benefit from emplace_back which should avoid any construct/move/release overheads you're incurring.

emplace_back will still call the allocator though...

Alternatively it might help if you 'move' the value in:

list.push_back(std::move(v));

That's assuming you've defined useful move semantics on your element type.

like image 22
Persixty Avatar answered Sep 22 '22 03:09

Persixty


Yes, push_back from std::list creates a new object on heap using new (or malloc()). It creates a copy of the argument.


Your second snippet is correct. aObj is copied.

In the third snippet copy of aObj will remain in the list, while aObj itself will be deleted.

like image 24
HolyBlackCat Avatar answered Sep 21 '22 03:09

HolyBlackCat


A std::list can contain objects or pointer to objects.

std::list<MyObj> list1;
list.push_back(MyObj()); // push an anonymous object (rvalue)
MyObj a;
list.push_back(a); // push (copy) a

std::list<MyObj*> list2;
list2.push_back(new MyObj());
MyObj* b = new MyObj();
list2.push_back(b);

list1 is a list of MyObj, when you clear the list, instances of MyObj inside the list are destroyed and the memory is freed. list2 is a list of pointers, when you clear the list, instances are not destroyed.

push_back creates a copy of the argument on the heap. But list2 is a list of pointers, so only the pointer is copied, not the object itself.

An anonymous object (called rvalue), due to its temporary behavior, may be "moved" inside the list: memory isn't allocated, but the pointer inside the list will point to the already allocated memory. This behavior depends on the type and on the implementation of push_back.

like image 39
Alessandro Pezzato Avatar answered Sep 21 '22 03:09

Alessandro Pezzato