1

In class Node:

class Node {
public:
    int data;
    int numchild;  
    Node** nodelist;

    Node(int data, int s);
};

I want an array of pointers (nodelist) to other nodes, which have edges from this node.

Is the following way of constructing such an array (and the above way of declaring it) a correct and the best (or easiest) way possible? If not, why and whats the best way?

Node::Node(int d, int s) {
    data = d;
    numchild = s;
    nodelist = new Node*[s];
}
5
  • 5
    Just use an appropriate STL container, like std::vector<Node*>. Commented Jun 27, 2011 at 19:43
  • 1
    I meant that it won't grow after creation.. it's not obvious from the example Commented Jun 27, 2011 at 19:50
  • @yi_H: if you look closer, the array size is passed by argument to the constructor. Commented Jun 27, 2011 at 19:53
  • @yi_H - Yeah it is fixed sized in that sense! Commented Jun 27, 2011 at 19:58
  • sure, I have to look closer to see that.. :/ Commented Jun 27, 2011 at 19:58

2 Answers 2

2

Generally you shouldn't reinvent the wheel. Raw arrays are almost always the wrong way to go. Have a look at the various containers from the STL, i.e. std::vector, std::list. I woud guess that in your case a std::vector might be the best solution.

If you want to stick with the raw array, a quick warning: new Node*[s] does not initialize the array, so the contents will be undefined. But if you add a set of parentheses (new Node*[s]()) it will be initialized to zero which is a good thing as it helps you spot which entries have been filled already.

Also, your current code lacks a destructor to delete[] the nodelist again. That's exactly why the use of standard containers is recommended: they have destructors that will do the work for you.

Sign up to request clarification or add additional context in comments.

7 Comments

Thanx for the vector suggestion, but i wanted to do it using raw array only.
And putting the parenthesis will initialize the pointers, right? it wont construct new Node objects and initialize them to zero?
It just zeroes the array. It won't construct single Node objects, you need to do that on your own. If you want to construct them at this time, with the same constructor arguments for all of them, you should make nodelist a Node* and do new Node[s];
@Nitin, out of interest, why wouldn't you want to use one of the existing containers? boost::ptr_vector or boost::ptr_array would fit nicely here. It would also handle things like making sure you get the expected behaviour in the copy constructor and operator=.
@Nitin: don't take it as disrespect, but I (or we?) still believe you should not use a raw array. Care to explain your reasoning for choosing it over a vector/list/etc? Or at least tell us your requirements?
|
1

Well, if you insist, but the answer will neither be the best nor the easiest, and correctness is very much your burden now.

For the constructor, use the base initializer list:

Node::Node(int d, size_t s)
: data(d), numchild(s), nodelist(new Node*[s])
{
}

We also make numchild an unsigned type, since it represents a size.

But now you also have to take care to deallocate the memory on destruction. A simple delete[] won't do because you first have to traverse all the children and recursively deallocate their memory.

All in all, a vector of shared pointers would save you about 90% of the code.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.