Home > Enterprise >  Array is not resizing with operator new
Array is not resizing with operator new

Time:03-08

I want to implement a dynamic array as a class.

I haven written a method which adds an element at the end of the array:

void DynamicArray::addElementAtEnd() {
    cout << "\nPodaj liczbe calkowita: ";
    int* number = new int;
    cin >> *number;

    if (DynamicArray::array == NULL) {
        DynamicArray::array = new int[1];
        DynamicArray::array[0] = *number;
        delete number;
        (*DynamicArray::size)  ;
        return;
    }
    int* buff = new int[*DynamicArray::size   1];
    memcpy(buff, DynamicArray::array, (*DynamicArray::size) * sizeof(int));
    delete[] DynamicArray::array;
    buff[(*DynamicArray::size)] = *number;
    DynamicArray::array = buff;
    (*DynamicArray::size)  ;
    delete number;
    return;
};

Here's the .h file of the DynamicArray class:

#include <iostream>
using namespace std;

class DynamicArray {
public:
    int* array;
    int* size;
public:
    DynamicArray() {
        DynamicArray::size = new int;
        *DynamicArray::size = 0;
    };
    void handleMenu();
    void readFromFile();
    void addElementAtEnd();
    void addElementAtBeginning();
    void addAtIndex(int index);
    void deleteElementAtEnd();
    void deleteElementAtBeginning();
    void deleteElementByIndex(int index);
    void showAllElements();
    void showElementAtIndex(int index);
    void findElementByValue(int value);
};

The problem is that this method adds only the first element, but if I try to add more then nothing happens. I debugged it, and the problem starts on this line:

int* buff = new int[*DynamicArray::size   1];

I don't know why, but it seems like this line is not creating a bigger array.

I searched for some solutions, and it seems that the problem is connected with using *DynamicArray::size 1 instead of eg a variable, or I don't do something right with it.

CodePudding user response:

The actual problem is that you are not initializing array to NULL. So when you check if array is NULL on the first iteration, it is often not.

The minimal solution:

DynamicArray::DynamicArray() {
  this->size = 0; // You should use 'size' like an int, not a pointer
  this->array = NULL;
}
// Or using the Member Initializer List (by @user4581301)
DynamicArray::DynamicArray(): size(0), array(nullptr) {}

Note: Differences between NULL and nullptr

Other simple solution could be to check if size is equal to 0 instead of checking if array is NULL.

The above change will solve your problem but your code can still be improved. Take into account the comments of other users. And make sure to free each dynamically allocated memory.

CodePudding user response:

Let's address a variety of things.

class DynamicArray {
public:
    int* array;
    int* size;
public:
    DynamicArray() {
        DynamicArray::size = new int;
        *DynamicArray::size = 0;
    }
};

A few things here. First, as others have suggested, there's zero reason to make size a pointer.

Next, it's a strong guideline / good idea to always initialize your fields when declared.

So this section of code can look like this:

class DynamicArray {
public:
    int* array = nullptr;
    int size = 0;
public:
    DynamicArray() {
    }
};

After that, please use nullptr instead of NULL. NULL is from C, but the correct value in C is nullptr.

Now, let's look at this bit of code.

void DynamicArray::addElementAtEnd() {
    cout << "\nPodaj liczbe calkowita: ";
    int* number = new int;
    cin >> *number;

    if (DynamicArray::array == NULL) {
        DynamicArray::array = new int[1];
        DynamicArray::array[0] = *number;
        delete number;
        (*DynamicArray::size)  ;
        return;
    }
    int* buff = new int[*DynamicArray::size   1];
    memcpy(buff, DynamicArray::array, (*DynamicArray::size) * sizeof(int));
    delete[] DynamicArray::array;
    buff[(*DynamicArray::size)] = *number;
    DynamicArray::array = buff;
    (*DynamicArray::size)  ;
    delete number;
    return;
};

Aside from the extra colon on the end of the function (entirely not necessary), this is far more complicated than it needs to be. First, get rid of the int pointer. That's just ridiculous.

void DynamicArray::addElementAtEnd() {
    cout << "\nPodaj liczbe calkowita: ";
    int number = 0;
    cin >> number;

    int * newArray = new int[size   1];
    newArray[size] = number;

    if (array != nullptr) {
        for (int index = 0; index < size;   index) {
             newArray[index] = array[index];
        }
        delete [] array;
    }
    array = newArray;
      size;
}

A last comment -- it would make far more sense to pass in the new value as an argument to the method, and the calling test code should get the value you're adding. But you're just learning, so this works.

Note also that you shouldn't specify the class the way you have: DynamicArray::array. No one does that. Do it the way I did above.

  •  Tags:  
  • c
  • Related