connormcwood
connormcwood

Reputation: 333

Using Memcpy to widen the size of an array of pointers

As the title suggests I am wanting to recreate an array which will have a different size than the original one.

My original array is created when a class is initiated and it is in the private member of the class. The array is called Node* arr[10]. It is set up with the size of ten originally and once the application requires more space for the length I wish to create a a new array using memcpy which will be the same as original arr but the only difference would be its max size.

Below is the code I have come up with however I am met with an error.

//Part Of Class
private:                
Node* arr[10];


//Part Of Method

size_t newSize = size * 2;
            Node** newArr = new Node*[newSize];
            memcpy(newArr, arr, size * sizeof(Node*));
            maxSize = newSize;
            delete[] arr;
            arr = newArr;

The error is shown at the last line, arr = newArr, and it states that it cannot convert from Node** to Node*[10]. Why exactly is this? Is it because Arr is initiated when the class first is?

Hovering over newArr shows Node** while hovering arr shows Node* Map::arr[10]. Could someone please explain my options with this as I am wanting to stick with arrays and I do not want to change over to vectors. I understand the issue is with them not being classed as the same type however if I remove the second asterisk on the newArr = new Node* ect line it says it cannot convert too.

Thank you for taking the type to read my issue and I hope the question is in the correct format, Regards

Upvotes: 0

Views: 631

Answers (2)

eerorika
eerorika

Reputation: 238341

Node* arr[10]

arr is an array of 10 pointers to Node.

What's more, it is an automatic member variable. It is stored as a sub-object of a "Class" instance.

delete[] arr;

You may not call delete[] on a member array. This has undefined behaviour. You may only call delete[] on a pointer (which arr is not) that was returned by a call to new[].

It is set up with the size of ten originally ...

The type of the member is "array of 10 objects". The type of a variable will never change during execution of the program. Therefore the size of the member will never change. If the size is 10 "originally", it is always 10.

Node** newArr

newArr is a pointer to a pointer to a Node. This is fundamentally different from an array.

= new Node*[newSize];

newArr is initialized to point to the first element of a dynamically allocated array of pointers.

arr = newArr;

This is wrong. You can not assign to an array.


Instead of a member array that cannot be resized, you could use a member pointer that can point to a dynamically allocated array. This member pointer can be assigned to point another, bigger array (just remember to not leak the previous array).

Manual memory management is easy to do wrong however, and it would be handy to wrap the member pointer that I described within a container that allocates the dynamic memory, and relases it on destruction. There already exists such container in the standard library: std::vector.

//Part Of Class
private:                
std::vector<Node*> arr = std::vector<Node*>(10);


//Part Of Method
arr.resize(arr.size() * 2);

Upvotes: 4

You need to make arr be of type Node**. Something like

size_t maxSize = 10;
Node** arr = new Node*[maxSize];

in the class declaration should do.

You now need a destructor (to free the memory), a copy constructor (to create a copy of the array), and a copy assignment operator (or you can delete the last two). If efficiency is important, you'll want a move constructor and a move assignment operator too.

Alternatively, rather than creating the initial arr on the heap, you could write:

static const initial_maxSize = 10;
size_t maxSize = initial_maxSize;
Node* initialArr[initial_maxSize];
Node** arr = &initialArr;  // Initialize arr to point at the array.

When you come to delete arr, you will need:

    if (arr != initialArr)
        delete [] arr;

... it's important not to delete something you didn't get from new.

Finally, really please reconsider using vectors. It makes a lot of this much simpler, and will have essentially no overhead over your own implementation (and is actually likely to be faster/more compact).

Upvotes: 0

Related Questions