declaring array of pointers

S

Steve Lambert

Hi,

I'd be grateful if someone could clarify this for me. In the linked list
structure my intention is to declare an array of length 3 containing
pointers to node
eg. Node *Iterators[3]
The compiler seems to interpret this as a pointer to an array of 3 nodes
instead. This interpretation ensures that the second assigment to mynode
below fails compilation with the given message.

Could someone explain to me how to correctly declare an array of length 3
containing pointers to node

cheers


#include <stdio.h>

typedef struct Node
{
void *Data;
struct Node *Next;
struct Node *Previous;
} Node;

/* structure to represent a linked list */
typedef struct LinkedList
{
Node *Head; /* start of linked list */
Node *Tail; /* end of linked list */
long NumberOfNodes;
short NumberOfIterators;
Node *Iterators[3];
} LinkedList;

LinkedList *mLinkedLists[2];


void main()
{
Node *mynode;
LinkedList *LL=NULL;

LL = mLinkedLists[0];

mynode = LL->Iterators[0]; <- this compiles

mynode = LL->Iterators; <- this doesn't : cannot convert from 'struct Node
*[3]' to 'struct Node *

printf("out\n");
}
 
B

Ben Pfaff

Steve Lambert said:
I'd be grateful if someone could clarify this for me. In the linked list
structure my intention is to declare an array of length 3 containing
pointers to node
eg. Node *Iterators[3]

That's the correct syntax.
The compiler seems to interpret this as a pointer to an array of 3 nodes
instead. This interpretation ensures that the second assigment to mynode
below fails compilation with the given message.

It's a misunderstanding of the error message, not a problem with
the compiler.
/* structure to represent a linked list */
typedef struct LinkedList
{ ....
Node *Iterators[3];
} LinkedList;
....

Node *mynode;
LinkedList *LL=NULL;

LL = mLinkedLists[0];

mynode = LL->Iterators[0]; <- this compiles

mynode is type Node *.
LL->Iterators[0] is type Node *.
Fine.
mynode = LL->Iterators; <- this doesn't : cannot convert from 'struct Node
*[3]' to 'struct Node *

mynode is type Node *.
LL->Iterators is type Node *[3], just as you declared it.
Problem: you can't assign a Node *[3] to a Node *.

The compiler's error message is slightly deceptive, because the
name of an array object is usually converted into a pointer to
the first element of the array. In this case, that means that
the actual type of the value being assigned is Node **. If you
defined mynode to be of type Node **, the second assignment would
be fine (although the first assignment would become invalid).

What are you trying to do with that statement?
 
D

Derrick Coetzee

Steve said:
Node *mynode;
mynode = LL->Iterators[0]; <- this compiles
mynode = LL->Iterators; <- this doesn't : cannot convert from 'struct Node
*[3]' to 'struct Node *

Your essential problem here is that "mynode" is a Node*, and
LL->Iterators is an array of Node*. These types are naturally
incompatible, just as you can't assign an array of int into an int (an
array is not an integer.)

On the other hand, you *can* assign an array of int to an int*. This is
because when used in expression contexts, the name of an array "decays"
into a pointer to its first element implicitly. In your case,
LL->Iterators would "decay" into &LL->Iterators[0], which has type
Node** (which is still incompatible with Node* mynode).
 
J

James Dow Allen

Steve Lambert said:
... In the linked list
structure my intention is to declare an array of length 3 containing
pointers to node
eg. Node *Iterators[3]

You did. "Size 3" is more idiomatic than "length 3" I think.

mynode = LL->Iterators[0]; <- this compiles
"//" and "/* */" are syntax for comments
-- use them even for meta-comments!
mynode = LL->Iterators; <- this doesn't

Whatever and Whatever[0] are always of different types
(the former often a pointer to the latter) -- why would
you expect *both* statements to compile?

James
 
A

Al Bowers

Steve said:
Hi,

I'd be grateful if someone could clarify this for me. In the linked list
structure my intention is to declare an array of length 3 containing
pointers to node
eg. Node *Iterators[3]
The compiler seems to interpret this as a pointer to an array of 3 nodes
instead. This interpretation ensures that the second assigment to mynode
below fails compilation with the given message.

Could someone explain to me how to correctly declare an array of length 3
containing pointers to node

cheers


#include <stdio.h>

typedef struct Node
{
void *Data;
struct Node *Next;
struct Node *Previous;
} Node;

/* structure to represent a linked list */
typedef struct LinkedList
{
Node *Head; /* start of linked list */
Node *Tail; /* end of linked list */
long NumberOfNodes;
short NumberOfIterators;
Node *Iterators[3];
} LinkedList;

LinkedList *mLinkedLists[2];


void main()
{
Node *mynode;
LinkedList *LL=NULL;

LL = mLinkedLists[0];

mynode = LL->Iterators[0]; <- this compiles

It may compile but it is very flawed and will not run.
LL has the value NULL and does not point to storage.
Since you are trying to access storage that is not, the
execution will fail.

You can type the member Iterators as
Node *Iterators[3];
making Iterators point to an array of 3 Node pointers.
Make a LinkedList object
LinkledList mylist;
Then you can access or assign Iterators with code something
like this:
mylist.Iterators[0] = malloc(sizeof Node);
or
Node newnode;
mylist.Iterators[0] = &newnode;
and
mylist.Iterators[0]->Data = /* whatever */

One the other hand out might make the member Iterators:
Node (*Iterators)[3];
Iterators will point to an array of 3 Node objects (not pointers).
Here is an example, in function main below:

#include <stdio.h>
#include <stdlib.h>

typedef struct Node
{
int Data;
struct Node *Next;
struct Node *Previous;
} Node;

/* structure to represent a linked list */
typedef struct LinkedList
{
Node *Head; /* start of linked list */
Node *Tail; /* end of linked list */
size_t NumberOfNodes;
size_t NumberOfIterators;
Node (*Iterators)[3];
} LinkedList;
/* Prototypes */
int AddNode(LinkedList *p, int data, size_t IterNo);
void FreeLinkedList(LinkedList *p);

int main(void)
{
LinkedList myList = {NULL};
size_t i,j;

AddNode(&myList, 44,0);
AddNode(&myList,33,2);
printf("myList.NumberOfIterators = %u\n",
myList.NumberOfIterators);
for(i = 0; i < myList.NumberOfIterators;i++)
for(j = 0; j < 3; j++)
{
myList.Iterators[j].Data = i+j;
printf("myList.Iterator[%u][%u].Data = %d\n",
i,j, myList.Iterators[j].Data);
}
printf("\nmyList.Head->Data = %d\n",myList.Head->Data);
FreeLinkedList(&myList);
return 0;
}

int AddNode(LinkedList *p, int data, size_t IterNo)
{
Node *new;
Node (*itmp)[3];

if((new = malloc(sizeof *new)) == NULL) return 0;
itmp = realloc(p->Iterators,(sizeof *itmp)*IterNo);
if(IterNo && itmp == NULL)
{
free(new);
return 0;
}
p->Iterators = itmp;
p->NumberOfIterators = IterNo;
new->Data = data;
if(p->NumberOfNodes == 0)
{
new->Previous = new->Next = NULL;
p->Head = p->Tail = new;
}
else
{
new->Previous = NULL;
new->Next = p->Head;
p->Head->Previous = new;
p->Head = new;
}
p->NumberOfNodes++;
return 1;
}

void FreeLinkedList(LinkedList *p)
{
Node *tmp;

for(tmp = p->Head; tmp;p->Head = tmp)
{
tmp = p->Head->Next;
free(p->Head);
}
free(p->Iterators);
p->Head = p->Tail = NULL;
p->Iterators = NULL;
p->NumberOfIterators = p->NumberOfNodes = 0;
return;
}
 
P

pete

James said:
Steve Lambert said:
... In the linked list
structure my intention is to declare an array of length 3 containing
pointers to node
eg. Node *Iterators[3]

You did. "Size 3" is more idiomatic than "length 3" I think.

I agree.
Size is a dimension of objects.
Length is a dimension of strings.
 
T

Tim Rentsch

Derrick Coetzee said:
On the other hand, you *can* assign an array of int to an int*. This is
because when used in expression contexts, the name of an array "decays"
into a pointer to its first element implicitly. In your case,
LL->Iterators would "decay" into &LL->Iterators[0], which has type
Node** (which is still incompatible with Node* mynode).

I'm curious to know if anyone can shed some light as to the origin of
the phrase "decays into a pointer" when talking about the behavior
of array names used in C. It isn't in K&R (at least not that I
recall), and I don't remember seeing it in any of the other C books
I've read. Personally I find the term misleading, and suspect it
probably confuses C novices more than it helps them. Anyone have
any personal experiences, either pro or con, to report on that?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

array of pointers 3
Array of structs function pointer 10
memory delete problem 3
Linked list in C 4
Variable-sized lines of text in linked list 47
Pointers 16
Need help finding Segmentation fault C++ 0
Code reuse 9

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top