tags:

views:

103

answers:

4

Sorry if this question has been asked before. On my search through SO I didn't find one that asked what I wanted to know.

Basically, when I have this:

typedef struct node
{
    int data;
    node *node;
} *head;

and do node *newItem = new node;

I am under the impression that I am declaring and reserving space, but not defining, a pointer to struct node, is that correct?

So when I do

newItem->data = 100 and newItem->next = 0

I get confused. newItem = 0would declare what exactly? Both data and next? The object as a whole?

I'm especially confused when I use typedef. Which part is the macro? I assume node because that's how I call it, but why do I need it?

Finally, what happens when I do:

node *temp;
temp = new node;

temp = head->next;
head->next = newItem;
newItem->next = temp;

I mean, head->next is a pointer pointing to object newItem, so I assume not to newItem.data or next themselves. So how can I use an uninitialized pointer that I described above safely like here? is head now not pointing to an uninitialized pointer?

+8  A: 

I am under the impression that I am declaring and reserving space, but not defining, a pointer to struct node, is that correct?

No. You are declaring a pointer, allocating space on the stack for the pointer, and dynamically allocating storage for a node to it it.

Don't confuse yourself by writing stuff like this:

typedef struct node
{
    int data;
    node * next;
} *head;

The way to write the struct in C++ is:

struct node
{
    int data;
    node * next;
};

You can now create a pointer:

node * pnode;

which allocates storage for the pointer.

and you can dynamically allocate storage for a node, and make the pointer point to it:

pnode =  new node;

or do it all in one:

node * pnode = new node;

Now when you say:

pnode->data = 10;

you are not allocating anything. You are assigning 10 to the member called data of the node instance pointed to by pnode. Of course, if you had given your node a constructor (which you should normally do), you could do it all in one:

struct node
{
    int data;
    node * next;

    node( int n, node * np ) : data( n ), next( np ) {}
};

node * pnode = new node( 10, 0 );
anon
+3  A: 
node *newItem = new node;

You create:

  • a new node on the heap (which in your case contains uninitialized values because you omitted the ()
  • a pointer on the stack, which points to this new node.

    newItem->data = 100

simply sets the data member of the newly allocated node to 100.

jalf
+3  A: 

When you define your struct as you did and call new like you did, what you're doing is:

  1. allocate a new struct node on the heap.
  2. allocate space on the stack for newItem and set its value to the address of the new struct you allocated.

You didn't set any values to any of the members of the new struct. If you want that to happen whenever you create a new instance of the struct, you need to define a constructor.

Nathan Fellman
+3  A: 
typedef struct node
{
    int data;
    node *node;
} *head;

This declares node as a struct and defines head as a synonym for node*, so head is a type and not an object.

This makes this illegal: temp = head->next; because -> is not something that you can apply to a type.

new node dynamically allocates a node object and returns a pointer to it. node *newItem = new node; assigns this pointer to newItem. Note, though, that newItem->node (node here is a pointer object and not the type node) is not initialized so is neither null nor points to a valid node object.

This is also illegal because node has no next member.

newItem->next = temp;

I suggest that you choose a naming convention that means that you keep your types and your variables separate. It is somewhat confusing.

Charles Bailey