2. I'm not sure what you mean. Am I not using an array of pointers now? How can I add new nodes to the end? |
I copy your code here to make it easier to reference.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
int main(int argc, const char * argv[]) {
std::cout<<"Start main"<<std::endl;
Node* tmp= new Node[3];
std::cout<<"Checkpoint main"<<std::endl;
for(int i=0;i<3;i++){
tmp[i]=*new Node(4);
}
delete[] tmp;
tmp=NULL;
std::cout<<"End main"<<std::endl;
return 0;
}
|
The short answer is "no". You are not using an array of pointers.
In line 4 you dynamically allocate an array of 3 Node objects that are contiguous on the heap. The value of tmp is a single pointer to a Node that happens to point to the first Node in the array. Subsequent Nodes in the array can be accessed using pointer arithmetic (tmp + 1), or array indexing (tmp[1]). Pointer arithmetic yields a new pointer pointing to another Node in the array. Array indexing yields an actual Node in the array--i.e. the pointer has already been dereferenced.
Both of the above assume that the bounds of the array have not been violated
So, the following statements would be true:
1 2
|
tmp + 2 == &tmp[2]
*(tmp + 1) == tmp[1]
|
So, you have an array of Node objects with a single pointer--not an array of pointers to Nodes.
In line 7 you are dynamically creating another Node object and then copying its contents into the array. The newly created Node object is subsequently ignored, and you have a memory leak.
Compare this with option #2 provided by @kbw.
1 2 3 4
|
typedef Node* PNode;
Node** tmp= new PNode[3];
for (size_t i = 0; i != 3; ++i)
tmp[i] = new Node(4);
|
In this code block, line 2 actually dynamically allocates an array of pointers-to-Node. So, there are 3 pointers (to Node) allocated contiguously on the heap. The value tmp now contains the address of the first pointer in the Array. Thus, the type of tmp is a Node** (a pointer to a pointer to a Node). Line 4 subsequently allocates a single Node object (dynamically) and places it address into the array. It is also possible, if you wish, to allocate an array of Node objects and place the address of the first element in each array into the tmp element. This would give you a jagged 2-dimensional array.
The upshot is, use vectors. There is no noticeable overhead, it's safer, and you can create the elements as you need them without copying (using emplace_back). And if you need multiple-dimension arrays, you can simply write the following:
1 2
|
std::vector<std::vector<Node> > twoDimensionalArray;
std::vector<std::vector<std::vector<Node> > > threeDimensionalArray;
|
By the way, I wouldn't mess around with the replacement new suggested above. It can be done, but going back to C constructs to play with memory allocation and then using a rarely-used version of
new
seems to be the wrong solution in my mind.