-1

I filling std::list List. How to do it properly?

When I did this:

objekt * obj = new objekt();
objekt ** objP = &obj;
List.push_back(objP);

or this

objekt * obj = new objekt();
List.push_back(&obj);

it is working. But when I did it inside loop

// Loop 1
for (int i = 0; i < 2000; i++, mi++)
{
    if (mi >= 37) mi = 0;
    objekt * obj = new objekt(name[mi], i+1);
    List.push_back(&obj);
}

it make all pointers inside List point in to last created object. That means, all object ** ObjectPointer point to one objekt * obj. It looks like objekt * obj is created only once and each loop only create new objekt, therefore each item in List point to one adress objekt. I always thinked that objekt inside loop are new object for each round (code above).

Therefore I create new for Pointer to pointer.

// Loop 2
for (int i = 0; i < 2000; i++, mi++)
{
    if (mi >= 37) mi = 0;
    objekt * o = new objekt(name[mi], i+1);
    List.push_back(new objekt*(o));
}

Now each pointer to pointer inside List have unique objekt not same.

This is how I free list

std::list<objekt**>::iterator itL = List.begin();
while (itL != List.end())
{
    objekt ** po = *itL;
    objekt *& o = *(*itL);
    List.erase(itL);
    delete o;
    delete po;
    o = nullptr;
    po = nullptr;
    itL = List.begin();
}

Questions are

  1. why first loop (Loop 1) is different as second loop (Loop 2) which fill List?

  2. when I insert objekt like this:

    objekt * obj = new objekt();
    List.push_back(&obj);

    should I delete pointer to pointer inside List? (I don't mean object created with new)

    objekt ** po = *itL;
    delete po;
SergeyA
  • 61,605
  • 5
  • 78
  • 137
Wanderer
  • 319
  • 1
  • 3
  • 12
  • You should consider using smart pointers: https://stackoverflow.com/questions/106508/what-is-a-smart-pointer-and-when-should-i-use-one – infinitezero Jan 07 '19 at 16:21
  • 3
    There's almost never a reason to use pointers to pointers. There is rarely a reason to use raw pointers at all. Please read any good C++ tutorial, it explains how to use container. Also, in case that's your background, don't try to write Java code (lots of `new`) in C++! – Ulrich Eckhardt Jan 07 '19 at 16:22
  • 1
    Most likely, your should simply store objects in your list, not pointers to them, and certainly not pointers to pointers. – SergeyA Jan 07 '19 at 16:30

2 Answers2

0

You are storing a pointer to obj, not what it contains.

So in the List you have i pointers to obj.

The line :

List.push_back(&obj);

Should be :

List.push_back(obj);
Robert Andrzejuk
  • 5,076
  • 2
  • 22
  • 31
-1

I always thinked that objekt inside loop are new object for each round (code above).

You've thinked correctly.

it make all pointers inside List point in to last created object.

Actually, all of the pointers (of type objekt **) point to objects (of type objekt *) that have been destroyed. They are said to be "dangling". Indirecting a dangling pointer has undefined behaviour.

It looks like objekt * obj is created only once and each loop only create new objekt

Undefined behaviour can look like anything.

  1. why first loop (Loop 1) is different as second loop (Loop 2) which fill List?

In first loop your pointers are automatic variables declared within the loop body. Since they have automatic storage, the variables are destroyed at the end of the scope (the loop body in this case). As such, the pointers in the vector are dangling and indirecting them has undefined behaviour.

In the second loop your pointers have dynamic storage. They are not destroyed until they are deleted. As such, there are no dangling pointers and indirecting the pointers is well defined.

  1. should I delete pointer to pointer inside List? (I don't mean object created with new)

You must delete all pointers returned by new or else memory will leak. You must not delete anything else or else the behaviour will be undefined.

In the case of second example, *itL was created with new so it must be deleted.

eerorika
  • 232,697
  • 12
  • 197
  • 326