Can't set pointers to dynamic arrays equal to eachother correctly

I have a project in my programming class. In the project I need to create a dynamically allocated array in a template class. One of the things the class needs to do is be able to add and subtract elemtents within it, and adjust the size of the array to fit the changes. The size of the array is incremented or decremented by a "CHUNK" size, all this is is a global constant. For instance, if I wanted to create a template array and populate it with 5 integers, given a chunk size of three, I need to be able to fill the template array and increase its size dynamically to fit those elements.

The function that takes care of this is called "add". The add function adds one element at a time to the array and need to be able to increase the size of the array if the array is not big enough to add it. The barebones of my program looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <iostream>
using namespace std;

const int CHUNK = 3;

template < class T> class RubberArray
{
private:
T* _array; //the template array 
unsigned _length; //the number of element in the array

public:
RubberArray ()
{
        _array = new T[CHUNK];
        _length = 0;
}
RubberArray( const RubberArray& n)
{
        _array = n._array;
        _length = n._length;
}

~RubberArray( )
{
        delete[] _array;
}


void add ( const T& n)
{
        if (_length%CHUNK == 0 && _length != 0)//checks that the array is not full. If the array is full _length will be a multiple of CHUNK and the % will be equal to 0 
        {
                T* temp = new T[_length + CHUNK];//create temp array of the appropriate size
                for (int i = 0; i < _length; i++)
                {
                        temp[i] = _array[i];//member by member copy
                }

                _array = temp;//set data member equal to the temp array and delete it.
                delete[] temp;
        }

        _array[_length++] = n;
};

friend ostream& operator<< ( ostream& os, const RubberArray& n)
{
        for (int i = 0; i < n._length; i++)
        {
                os << n._array[i] << ", ";
        }

        return os;
}

int main()
{

 RubberArray <int> i(0);
 i.add(1);
 i.add(2);
 i.add(3);
 i.add(4);
 cout << i << endl //

}


The output looks something like this. I am coding in a linux environment for reference:
0, 2, 3, 4,
*** glibc detected *** ./a.out: double free or corruption (fasttop): 0x09759018 ***
======= Backtrace: =========
/lib/i386-linux-gnu/i686/cmov/libc.so.6(+0x6aac1)[0xb74ccac1]
/lib/i386-linux-gnu/i686/cmov/libc.so.6(+0x6c328)[0xb74ce328]
/lib/i386-linux-gnu/i686/cmov/libc.so.6(cfree+0x6d)[0xb74d13dd]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZdlPv+0x1f)[0xb76b1abf]
./a.out[0x8048acf]
/lib/i386-linux-gnu/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0xb7478e46]
./a.out[0x8048831]
======= Memory map: ========
08048000-0804a000 r-xp 00000000 fe:04 565316     /home2/tadlockk/project6/a.out
0804a000-0804b000 rw-p 00001000 fe:04 565316     /home2/tadlockk/project6/a.out
09759000-0977a000 rw-p 00000000 00:00 0          [heap]
b7300000-b7321000 rw-p 00000000 00:00 0
b7321000-b7400000 ---p 00000000 00:00 0
b7460000-b7462000 rw-p 00000000 00:00 0
b7462000-b75b5000 r-xp 00000000 fe:00 24281      /lib/i386-linux-gnu/i686/cmov/libc-2.13.so
b75b5000-b75b6000 ---p 00153000 fe:00 24281      /lib/i386-linux-gnu/i686/cmov/libc-2.13.so
b75b6000-b75b8000 r--p 00153000 fe:00 24281      /lib/i386-linux-gnu/i686/cmov/libc-2.13.so
b75b8000-b75b9000 rw-p 00155000 fe:00 24281      /lib/i386-linux-gnu/i686/cmov/libc-2.13.so
b75b9000-b75bc000 rw-p 00000000 00:00 0
b75bc000-b75d8000 r-xp 00000000 fe:00 24370      /lib/i386-linux-gnu/libgcc_s.so.1
b75d8000-b75d9000 rw-p 0001b000 fe:00 24370      /lib/i386-linux-gnu/libgcc_s.so.1
b75d9000-b75da000 rw-p 00000000 00:00 0
b75da000-b75fe000 r-xp 00000000 fe:00 24149      /lib/i386-linux-gnu/i686/cmov/libm-2.13.so
b75fe000-b75ff000 r--p 00023000 fe:00 24149      /lib/i386-linux-gnu/i686/cmov/libm-2.13.so
b75ff000-b7600000 rw-p 00024000 fe:00 24149      /lib/i386-linux-gnu/i686/cmov/libm-2.13.so
b7600000-b76e2000 r-xp 00000000 fe:01 88438      /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b76e2000-b76e6000 r--p 000e2000 fe:01 88438      /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b76e6000-b76e7000 rw-p 000e6000 fe:01 88438      /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b76e7000-b76ee000 rw-p 00000000 00:00 0
b76fb000-b76fe000 rw-p 00000000 00:00 0
b76fe000-b76ff000 r-xp 00000000 00:00 0          [vdso]
b76ff000-b771a000 r-xp 00000000 fe:00 24272      /lib/i386-linux-gnu/ld-2.13.so
b771a000-b771b000 r--p 0001b000 fe:00 24272      /lib/i386-linux-gnu/ld-2.13.so
b771b000-b771c000 rw-p 0001c000 fe:00 24272      /lib/i386-linux-gnu/ld-2.13.so
bff52000-bff67000 rw-p 00000000 00:00 0          [stack]
Aborted


My problem, I think, is the assignement
 
_array = temp


isn't the correct statement. I don't know what the correct statement should be though. Help getting this to work would be great.

Thanks for any help.
Last edited on
1
2
_array = temp;//set data member equal to the temp array and delete it.
delete[] temp;


Shouldn't you be deleteing what array used to point to, not what you've just set it pointing at?
So should I be doing something like:

1
2
3
delete[] _array;
_array = temp;
delete temp;


?

EDIT: Both are pointers to arrays, so I am pretty confused as to wether making _array = temp makes _array and alias for the pointer temp, or an alias for the data pointed to by temp. Its all very confusing.
Last edited on
What do you think delete does?

If you do this
_array = temp;
you make the pointer _array point to some memory, yes? The same memory that temp points to.

So if you then
delete[] temp;
you are instructing that you no longer care about the memory temp points to... which is the same thing array points to! But you do care about that memory - you're using it as your replacement, bigger array.

Try this:
1
2
delete[] _array;
_array = temp;

Last edited on
Ok, thanks I will. One questions, can I delete the pointer "temp" as well? Or will that not be neccessary, because it will fall out of scope as soon as the function returns?
delete does not act on the pointer. delete acts on the memory the pointer is pointing to. When you "delete a pointer", the pointer remains in existence; all it does is mark the memory the pointer is pointing to as no longer being memory that you care about. That's it. The pointer does not in any way get removed.

At the end of the add function, is the pointer temp pointing at memory that you still care about?

I haven't checked. I am pretty sure it will fall out of scope because I created it locally within add, so I shouldn't need to worry about it. I am just new to dynamic memory and wanted to be thorough. In any event, that fix worked! I am no longer having memory issues and the output looks correct. Thank you so much.
wanted to be thorough


You were using delete on the same memory twice, through your need to be thorough. That's what caused the crash.
Topic archived. No new replies allowed.