Reputation: 505
What is the use and explanation of something like this?:
int capacity;
int** number;
this->number = new int*[this->capacity];
I'm studying for an exam and in a test exam they put the requirement of using a pointer-to-pointer object and making a dynamic array from it. There are two classes; Wallet & WalletKeeper. In the solutions they did this in the header-file of WalletKeeper:
private:
Wallet** wallets;
int capacity;
int size;
/*other stuff below this*/
And in the constructor:
WalletKeeper::WalletKeeper(int capacity)
{
this->capacity = capacity;
this->size = 0;
this->wallets = new Wallet*[this->capacity];
this->initiate();
}
I understand a basic dynamic array like this:
Wallet * wallets = new Wallet[capacity];
This would mean you make a pointer which points to the place in the memory where this array of Wallets is made, so you can change the content of those memory slots. But why would you ever make a pointer to an array of pointers? What's the use?
Wallet has no array of its own, I would've understood it otherwise because I read this: The correct way to initialize a dynamic pointer to a multidimensional array?
Professors are on vacation until further ado.
Upvotes: 1
Views: 136
Reputation: 9725
A pointer to pointers-objects is common used for matrices implementation. Indeed like pointers to objects implement dynamic array, as you've suggested in your question:
Wallet* wallets = new Wallet[capacity];
makes wallets points the first location of an array to num-capacity Wallet
object.
[Wallet-obj] [Wallet-obj] [Wallet-obj] ... [Wallet-obj]
0 1 2 capacity - 1
Pointer of pointers like:
Wallet** wallets = new Wallet*[capacity];
Create an array of Wallet pointer:
[Wallet-pointer] [Wallet-pointer] [Wallet-pointer] ... [Wallet-pointer]
0 1 2 capacity-1
Each pointer in the vector should point to an dynamic array.
I'll try to "draw" a representation:
[0][wallet-pointer] ----> [0][wallet obj] [1][wallet obj] ... [capacity-1][wallet obj]
[1][wallet-pointer] ----> [0][wallet obj] [1][wallet obj] ... [capacity-1][wallet obj]
...
[capacity-1][wallet-pointer] ----> [0][wallet obj] [1][wallet obj] ... [capacity-1][wallet obj]
So in order to access to an object you should use something like:
wallets[0][2];
That means access the 1-st pointer in the array of pointer, using the 1 "row" of object access to the 3-rd object of that row.
So as you can image, you have a matrix because you have a n-capacity dynamic array, like n-capacity rows.
When you instantiate an array of pointers, you have to initialize each of them. This is a complete code:
Wallet** wallets = new Wallet*[capacity];
// Now for each pointer you have to allocate a dynamic array of n-elements.
for (size_t i = 0; i < capacity; ++i) {
wallets[i] = new Wallet[capacity];
}
And the same is for deallocation phase:
// First of all, deallocate each object in each dynamic array:
for (size_t i = 0; i < capacity; ++i) {
delete[] wallets[i]; // wallets[i] is a dynamic array to deallocate
}
// Finally deallocate the dynamic array of poiter
delete[] wallets;
Upvotes: 0
Reputation: 20396
The basic idea is that it allows you to create an "array of arrays". It has a narrow advantage over a matrix in that it allows you to have differently sized sub-arrays, but a disadvantage in that the memory of all objects is no longer contiguous across the entire array.
Wallet ** w_ptr_ptr = new Wallet*[capacity];
for(int i = 0; i < capacity; i++) {
w_ptr_ptr[i] = new Wallet[i+1];
}
for(int i = 0; i < capacity; i++) {
for(int j = 0; j < i+1; j++) {
w_ptr_ptr[i][j] = Wallet(/*...*/);
}
}
Note that in that code, w_ptr_ptr[0]
has a differently sized array than w_ptr_ptr[1]
.
As I alluded to in my comment though, your professor shouldn't be teaching like this. Because this code requires manual memory cleanup, and doesn't have any capacity to do automatic bounds checking, the code you should be using is:
std::vector<std::vector<Wallet>> wallets;
for(int i = 0; i < capacity; i++) {
wallets.emplace_back(i+1); //Will automatically create a i+1-sized array.
}
for(int i = 0; i < wallets.size(); i++) { //Note I'm able to query the size here!
for(int j = 0; j < wallets[i].size(); j++) { //Again I can query the size!
wallets[i][j] = Wallet(/*...*/);
}
}
Upvotes: 1
Reputation: 1879
There are many uses of arrays of pointers.
Upvotes: 3