0

I got really stuck trying to deallocate memory using delete without it being in a for loop.

    MyClass *Array[10];

cout << "Step 1 - Allocation" << endl << endl;
Array[0] = new MyClass();
Array[1] = new MyClass();
Array[2] = new MyClass(2, 4.6);
Array[3] = new MyClass(*Array[2]);
Array[4] = new MyClass();
Array[5] = new MyClass(13, 66.6);
Array[6] = new MyClass(75, 9.43);
Array[7] = new MyClass(*Array[6]);
Array[8] = new MyClass(*Array[1]);
Array[9] = new MyClass(*Array[3]);

cout << endl << "Step 2 - Write" << endl << endl;
for(int i=0; i<10; i++)
{
    Array[i]->write();
    cout << endl;
}

cout << endl << "Step 3 - Deallocation" << endl << endl;

I tried delete[] Array, but it doesn't work.

The code must stay as it is as it's correct by what is asked to do. The only thing is to add a delete (single-lined and not a for loop) to delete Array.

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Tr3LoS
  • 3
  • 3
  • 3
    What you mean by 'it doesn't work?'???... – Vite Falcon May 24 '12 at 16:31
  • I compile but it drops error at that point – Tr3LoS May 24 '12 at 16:33
  • 1
    for loop will be what you need to get rid of the objects you allocated into your bare pointer array, as the fixed array of bare pointers all point to memory you allocated. You could try using smart pointers to manage the objects you allocate, so they will be cleaned up (deleted) when the array goes out of scope. – StarPilot May 24 '12 at 16:34
  • @user1415587: Always show the full text of the errors, because otherwise we can't really help you. – Mooing Duck May 24 '12 at 16:35
  • I'm compelled to recommend a [good C++ book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – R. Martinho Fernandes May 24 '12 at 16:38
  • So if there is no way to use a single line delete to delete the objects I will use the for loop as I know. It is just that the exersise asks to use a single lined delete to deallocate instead of a for loop. – Tr3LoS May 24 '12 at 16:42
  • @user1415587 in that case, you probably wanted a array of `MyClass` _objects_ instead of an array of `MyClass` pointers. _That_ could be cleaned in one line. – Mooing Duck May 24 '12 at 16:48
  • 2
    `std::for_each(std::begin(Array), std::end(Array), std::default_delete());` – R. Martinho Fernandes May 24 '12 at 16:59

7 Answers7

8

You need to delete each object that you've created using new:

for (unsigned i(0); i < 10; ++i)
    delete Array[i];

Array itself is a local variable; you did not use new to create it, so you do not use delete to destroy it. It will be destroyed when it goes out of scope.

To address the updated constraint that the deletion must be done "single-lined and not a for loop," one could, I suppose, write:

delete Array[0]; delete Array[1]; delete Array[2]; delete Array[3]; delete Array[4]; delete Array[5]; delete Array[6]; delete Array[7]; delete Array[8]; delete Array[9];

This is a single line of code and uses no loops. It is not possible to use a single delete expression to destroy what are ten effectively unrelated objects.


But do not do this. Really. Manual resource management is dangerous and very difficult to do correctly. C++ has automatic resource management capabilities and you should use them. In this case, it would be far better to use a std::vector<MyClass>:

std::vector<MyClass> Array;
Array.push_back(MyClass());
Array.push_back(MyClass());
Array.push_back(MyClass(2, 4.6));
Array.push_back(MyClass(Array[2]));
// Etc.

There's no new in this example, thus no delete is required. The std::vector will clean everything up when it is destroyed.

Praetorian
  • 106,671
  • 19
  • 240
  • 328
James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • If you're really lucky, you can do `Array.emplace_back(2, 4.6);` – Steve Jessop May 24 '12 at 16:38
  • The code must stay as it is. The only problem I have is that I need to use delete as a single lined command to delete the Array. Deleting it in a for loop is a piece of cake, but I got stuck trying to do it in a single line. I tried delete[] Array but it doesnt work (debugs ok but at execution it breaks). – Tr3LoS May 24 '12 at 16:47
  • @DeadMG oops, sorry for the tag, I edited the question and added some info – Tr3LoS May 24 '12 at 16:54
  • Thanks, I will use the for loop and contact tommorow my teacher to ask what was the case and if there was an error in exersise. – Tr3LoS May 24 '12 at 17:01
  • 3
    @DeadMG: This isn't reddit; there is no reason to berate people here in the comments, especially someone about whom you know very little, and who is not present to defend himself. – James McNellis May 24 '12 at 17:04
6

Operator delete[] must be used in conjunction with operator new[], which you haven't used here. You manually new'ed every single instance of MyClass. You have to manually delete every single instance of MyClass.

user703016
  • 37,307
  • 8
  • 87
  • 112
5

delete[] is used to delete something that was allocated by new[], it does not call delete for each of the elements of an array. You have to call delete on each of your array elements within a loop.

K-ballo
  • 80,396
  • 20
  • 159
  • 169
4
std::vector<std::unique_ptr<MyClass>> Array;
Array.resize(10);

No delete required.

Puppy
  • 144,682
  • 38
  • 256
  • 465
  • Don't use a unique_ptr. Use a shared_ptr. Less prone to losing your managed resource when accessing the vector contents. – StarPilot May 24 '12 at 16:40
  • 2
    @StarPilot: Don't use `shared_ptr` unless ownership is shared (which is virtually never). Use `unique_ptr` almost always. Maybe you're thinking of `auto_ptr`? – Mooing Duck May 24 '12 at 16:42
  • 3
    vector has a constructor that takes a size argument. It suffices to just say - 'std::vector> Array(10);' – Happy Green Kid Naps May 24 '12 at 16:56
0

I got really stuck trying to deallocate memory using delete without it being in a for loop.

If you don't allocate memory manually, you don't need to deallocate memory manually.

    MyClass Array[10] = {
        MyClass(),
        MyClass(),
        MyClass(2, 4.6),
        MyClass(Array[2]),
        MyClass(),
        MyClass(13, 66.6),
        MyClass(75, 9.43),
        MyClass(Array[6]),
        MyClass(Array[1]),
        MyClass(Array[3])
    };

    // there's nothing to delete now

new or delete are advanced C++ features that have some niche uses. Don't use them if you don't need to.

R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
0

You can use a deleter functor such as this one and do something like:

for_each(Array.begin(), Array.end(), free_ptr<C>());
Nemanja Trifunovic
  • 24,346
  • 3
  • 50
  • 88
-1

The only way I can see cleanup in one line is if you rewrite it so that Array is a pointer to an array of objects, instead of being a array of pointers.

MyClass *Array = nullptr;

cout << "Step 1 - Allocation" << endl << endl;
Array = new MyClass[10];
Array[0] = MyClass(); //removed "new"
...

cout << endl << "Step 2 - Write" << endl << endl;
for(int i=0; i<10; i++)
{
    Array[i].write(); //Objects aren't pointers anymore
    cout << endl;
}

cout << endl << "Step 3 - Deallocation" << endl << endl;
delete[] MyClass;
Mooing Duck
  • 64,318
  • 19
  • 100
  • 158
  • new must not be removed, in fact nothing must be removed. Maybe it is a mistake from the teacher and I should use a for loop instead. – Tr3LoS May 24 '12 at 16:58
  • @Tr3LoS: If you can't use a loop, and can't change the type of `Array`, then either (A) The teacher is wrong, or (B) There was miscommunication between you and the teacher. – Mooing Duck May 24 '12 at 17:13