leon
leon

Reputation: 181

Transfer Dynamic Array to new Dynamic Array, Delete Dynamic array filled with Dynamic Objects

If i create a dynamic array of Zebras, and then say, i make a new Temp array where i want to transfer the objects in the original array.

I then move pointer from original Array to Temp. do i need to delete the old array items before move array = temp?

Also, I seem to leak but not sure why, i appear to delete both arrays and the pointers.

class Zebra {

public:
    //int age = 0;

};

int main() {
    
    Zebra** array = new Zebra * [10];

    for (int i = 0; i < 10; i++) {
        array[i] = new Zebra;
    }

    Zebra** temp = new Zebra * [20];
    for (int i = 0; i < 10; i++) {
        temp[i] = array[i];
    }
    // do i need to delete the old array items before move array = temp?
    array = temp;
    delete[]temp;
    temp=NULL;

    for (int i = 0; i < 10; i++) {
        delete[]array[i];
        array[i]=NULL;
    }

    
    delete[]array;

    array= NULL;
}

Upvotes: 0

Views: 78

Answers (1)

David C. Rankin
David C. Rankin

Reputation: 84531

You have what you are deleting backwards, you want:

    delete[] array;
    array = nullptr;
    
    array = temp;

    for (int i = 0; i < 10; i++) {
        delete array[i];
        array[i] = NULL;
    }
    delete[] array;
    array = NULL;

Note, you also had a mismatched use of delete[] where delete alone should be used in freeing the array[i] elements.

Why does this work this way?

Originally you allocate for the pointer array creating a block of memory holding ten pointers to Zebra. When you then create temp twice as large as array and assign each pointer in array to temp, your temp holds the starting address for each array[i] (where 0 <= i < 10).

All you do is delete[] array, which frees the block of memory holding the original storage for 10 pointers to Zebra. When you assign array = temp; now array points to the new block of memory of 20 pointers to Zebra.

So in your reallocation scheme, you have just created a larger block of pointers, assigned all from array to temp, deleted the original block of pointers, and assigned the new block of pointers to array (done). (essentially doing what realloc() does in C)

The full example would be:

#include <iostream>

class Zebra {

public:
    //int age = 0;

};

int main() {
    
    Zebra **array = new Zebra*[10];

    for (int i = 0; i < 10; i++) {
        array[i] = new Zebra;
    }

    Zebra **temp = new Zebra*[20];
    for (int i = 0; i < 10; i++) {
        temp[i] = array[i];
    }
    
    delete[] array;
    array = nullptr;
    
    array = temp;

    for (int i = 0; i < 10; i++) {
        delete array[i];
        array[i] = nullptr;
    }
    delete[] array;
    array = nullptr;
}

Memory Use/Error Check

valgrind ./bin/zebra
==22402== Memcheck, a memory error detector
==22402== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==22402== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==22402== Command: ./bin/zebra
==22402==
==22402==
==22402== HEAP SUMMARY:
==22402==     in use at exit: 0 bytes in 0 blocks
==22402==   total heap usage: 13 allocs, 13 frees, 72,954 bytes allocated
==22402==
==22402== All heap blocks were freed -- no leaks are possible
==22402==
==22402== For counts of detected and suppressed errors, rerun with: -v
==22402== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Upvotes: 1

Related Questions