0

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
Saif Badran
  • 326
  • 4
  • 14
  • How was `elements` allocated? Does `Array` follow the [Rule of Three](http://stackoverflow.com/q/4172722/1782465), since it owns resources? In other words, post an [MCVE](http://stackoverflow.com/help/mcve), please. – Angew is no longer proud of SO Jul 03 '15 at 08:33
  • @nilo: that should actually be the correct way to do it - he deallocates the old array and assigns the pointer to the newly allocated one. What's wrong with that? – Ionut Jul 03 '15 at 09:07

2 Answers2

1

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
Ionut
  • 6,436
  • 1
  • 17
  • 17
  • Ok great but I didn't understand how to make it work now? :\ – Saif Badran Jul 03 '15 at 13:53
  • In `Array::Resize()`, when you set `elements` to point to the new buffer you allocated, you have to also update the size, like `size = newSize;`. – Ionut Jul 03 '15 at 13:57
  • Thank you my friend I did this and it worked perfectly! elements = new Type[newSize]; for(int i=0; i – Saif Badran Jul 03 '15 at 14:08
  • I'm not sure I understand the fragment from your comment correctly, but it looks like you're allocating the buffer a second time, which is not necessary. You just need to do `size = newSize;` after `elements = temp;` in the original implementation. – Ionut Jul 03 '15 at 14:11
  • Yes.. Ok i'll try that if it worked it'll be better of course – Saif Badran Jul 03 '15 at 14:37
-1

Couple of observations

if(newSize==size)

size does not exist

delete []elements;
    elements = temp;

You are attempting to copy to an array you have just deleted, which was never created in the first place.

What is meant by "does not work" and "the program works properly,"?

logbook
  • 45
  • 1
  • 5
  • We can probably assume that `size` and `elements` are members in the class `Array`, so they are defined. The two lines don't copy to an array that was just deleted, they delete the old array and then assign a pointer to the newly allocated one, which looks valid (at least from the little code shown above). – Ionut Jul 03 '15 at 08:47
  • That is probably correct lonut. But did my answer deserve a mark down, simply because I was fishing for more information? – logbook Jul 03 '15 at 09:23
  • what lonut said explains everything. I can post the whole header file if you need to? – Saif Badran Jul 03 '15 at 10:33
  • @SaifBadran please show us the full class definition and also, as logbook requested, tell us exactly what you mean by *works properly* and *doesn't do what is supposed to do* (ideally with a small example of working code). – Ionut Jul 03 '15 at 11:04
  • @lonut ok I've edited the question and added the class definition and implementation of all methods. i mean when i comment those two lines the program works with no errors and gives the full output but without resizing the array. but when these two lines are there i'm not getting a syntax error it's just gives the first couple lines of output then the program stops working, windows gives a message (project.exe has stopped working) and doesn't continue running . – Saif Badran Jul 03 '15 at 11:26