Search code examples
c++dynamicmemory-leaksresizedynamic-memory-allocation

Array resize function in dynamic memory


I'm making a function to resize an array in dynamic memory and it's not working..

here's the code:

template <class Type>
void Array<Type>::Resize(int newSize)
{
    if(newSize==size)
        return;
    if(newSize<=0)
        return;
    Type *temp = new Type[newSize];
    int min=(newSize>size)?size:newSize;

    for(int i=0; i<min; i++)
        temp[i]=elements[i];
    delete []elements;
    elements = temp;
    temp = NULL;
}

the problem is in these two statements

delete []elements;
    elements = temp;

cause when i comment them the program works properly,

but it actually doesn't do what is supposed to do..

I think the problem is something that is being destroyed when getting out of the function scope and I have to call it by reference but I can't actually cause this is a member function.

Here's the whole header file:

#include<string>
#include<iostream>
using namespace std;

#ifndef ARRAY_H
#define ARRAY_H

template <class Type>
class Array
{
public:
    Array (int s);
    Array (const Array& obj);
    ~Array ();

    const Array& operator= (const Array& obj);

    Type GetElement (int index) const;
    void SetElement (Type ele, int index);

    void Resize (int newSize);

    void Print () const;
    void Destroy ();

private:
    int size;
    Type* elements;

};

    template <class Type>
    Array<Type>::Array(int s)
    {
        if(s<0)
            return;
        size=s;
            elements = new Type[size];
    }

    template <class Type>
    Array<Type>::Array(const Array &obj)
    {
        size = obj.size;
        elements = new Type[size];
        for(int i=0; i<size; ++i)
            elements[i]=obj.elements[i];
    }

    template <class Type>
    Array<Type>::~Array()
    {
        delete [] elements;
        elements = NULL;
        size = 0;
    }

    template <class Type>
    void Array<Type>::Destroy()
    {
        delete [] elements;
        elements = NULL;
        size = 0;
    }

    template <class Type>
    const Array<Type> &Array<Type>::operator=(const Array &obj)
    {
        if(this != &obj)
        {
            size = obj.size;
            if(elements != NULL)
                delete [] elements;
            elements = new Type[size];

            for(int i=0; i<size; i++)
                elements[i] = obj.elements[i];
        }
        return *this;
    }

    template <class Type>
    Type Array<Type>::GetElement(int index) const
    {
        if(index<0 || index>=size)
            cout << "Sorry, this operation can not be proceeded \n";
        else
            return elements[index];
    }

    template <class Type>
    void Array<Type>::SetElement(Type ele, int index)
    {
        if(index<0 || index>=size){
            cout << "Sorry, this operation can not be proceeded \n";
            return; }
        else
            elements[index] = ele;
    }

    template <class Type>
    void Array<Type>::Print() const
    {
        for(int i=0;i<size; ++i)
            cout << elements[i] << endl;
    }

    template <class Type>
    void Array<Type>::Resize(int newSize)
    {
        if(newSize==size)
            return;
        if(newSize<=0)
            return;
        Type *temp = new Type[newSize];
        int min=(newSize>size)?size:newSize;

        for(int i=0; i<min; i++)
            temp[i]=elements[i];
        delete []elements;
        elements = temp;
        temp = NULL;

    }

#endif

Solution

  • You forgot to do one thing in the Resize() function, and that is to update the member size with the new size after reallocation. This will cause it to access memory beyond the end of the buffer after a resize with a smaller new dimension, e.g.:

    Array<int> arr(10);
    // set the 10 values
    
    arr.Resize(5);
    
    // here the buffer will have 5 elements, but arr.size is still 10
    
    arr.Print(); // this will read elements 0 - 9, not 0 - 4