-1

Some simple code show first:

Type A:

//create a queue

queue<my_class*> temp;
//add some element some pointers;

temp.push(A);
temp.push(B);
...

//then i want to delete the first element ;

temp.pop();

Question 1: When call temp.pop() it will release all the object memory A used? If not , what i should do ?

Type B:

//create a queue

queue<my_class> temp;
//add some element some pointers;

temp.push(A);
temp.push(B);
...

//then i want to delete the first element ;

temp.pop();

Question 2: What's difference with the Type A and Type B;

6502
  • 112,025
  • 15
  • 165
  • 265
iknow34languages
  • 173
  • 2
  • 12

2 Answers2

3

Q2: pop for Type A and Type B does the same thing, the pop destructs the type that is defined in the template argument (for Type A its a pointer to my_class for Type B it is my_class). So Type A destructs a pointer Type B destructs an instance of my_class.

Q1: Yes as A is just a pointer. But it does not destruct the object A is pointing to. So the instance of my_class is not released.

t.niese
  • 39,256
  • 9
  • 74
  • 101
2

pop() indeed destroys the first element.

Note however that in the first case the std::queue is of naked pointers and destroying a naked pointer doesn't do anything to the pointed-to object.

In the second case the std::queue contains object copies so when calling pop() the first copy will be destroyed and removed.

In the first case unless someone else knows the address of the object pointed to by the destroyed pointer and calls delete on that address, the object will be "leaked" (i.e. just forgotten about): its destructor will never be called and the memory it is using will never be reclaimed and reused for something else.

To destroy the pointed-to object in the first case the normal procedure is

delete queue.front();
queue.pop();

If instead of "naked" pointer you use "smart" pointers then the "leak" problem will go away in most cases(*). Note that it doesn't mean the destructor of the pointed-to object will be called in pop(), but that it will called at the appropriate time when no one else knows the address of the pointed-to object (if everything is done correctly when manipulating the smart pointers).


(*) If your data model is complex and you have std::shared_ptr networks of objects pointing to each other then there is a risk of creating "reference loops". In this case std::shared_ptr even if used correctly is not enough to prevent leaking of loops (e.g. leaking a cople of objects A and B where each one has a std::shared_ptr to the other) and a true garbage collector is needed. Unfortunately C++ doesn't provide this kind of machinery in the standard library.

6502
  • 112,025
  • 15
  • 165
  • 265
  • Instead of manually deleting, one should prefer smart pointers of course, like `std::queue>`. – chtz Aug 15 '19 at 08:12
  • @chtz Can you give me a demo code for how to use the std::queue> – iknow34languages Aug 15 '19 at 08:46
  • @chtz: I've added a note on smart pointers... they're good but it's important to remember they're not a silver bullet. The only option in C++ is to think hard to ownership (or implement/use a garbage collector). – 6502 Aug 15 '19 at 08:47
  • @6502 True, storing by value should always be the first option. Only if that is too expensive (or there is another constraint), storing (smart) pointers should be considered. At OP: https://stackoverflow.com/questions/14127487/remove-unique-ptr-from-queue – chtz Aug 15 '19 at 08:53