Re: structs help

From: Barry Schwarz (schwarzb_at_deloz.net)
Date: 04/04/04


Date: 4 Apr 2004 20:49:12 GMT

On Sat, 03 Apr 2004 22:36:05 -0600, Dave Cooke
<dcooke@ee.umanitoba.ca> wrote:

>Hi I am very new to C. I am trying to figure out how to initialize
>a struct in my main program.
>The struct is declared in anouther header file like this...
>typedef struct ln {
> int key;
> int data;
> struct ln *next;
>} listNode, *listNodePtr;
>
>just to test in my main method I tried to initialize the

C does not have methods. It has functions.

>listNodePtr variable to null like this...
>
>listNodePtr *head = NULL;
>
>First as far as I understand listNode and *listNodePtr are
>variables of type ln. However I have also learned, so I thought,

No. No neither is a variable. listNode is a typedef (a type alias)
for the type struct ln. listNodePtr is an alias for the type struct
ln*. *listNodePtr is exactly the same type as listNode.

>that listNodePtr is an alias to the struct ln. So my statement

No, as noted above, it is an alias to the type struct ln*.

>above should be legal. Is It?

Yes it is legal. (Your compiler did not generate a syntax error, did
it?) head has type struct ln** or pointer to pointer to struct ln.
Is it what you want? We can't tell; you did not show us the code that
uses it. Post a compilable program that exhibits the behavior you are
asking about.

>
>When I try to pass my new listNodePtr variable *head to my
>listInsert method like........
>
>listInsert(head,1,2);
>
>it doesn't work. It builds but at run time my program hangs

It either builds or it hangs. I have yet to see a program do both.

>when inside the listInsert method the first if condition
>tries to determine of the listNodePtr *list is null or not.
>i.e. if( *list == NULL )..... this is where the program quits.

Does it quit or does it hang?

>From what little code you have shown, this invokes undefined behavior.
The variable head in main is passed as an argument to listInsert,
corresponding to the parameter list. Both have the type struct ln**.
head is initialized to NULL. Therefore, this is the value assigned to
list at entry to listInsert. Your code attempts to dereference list
(that is what *list means). You are not allowed to dereference a NULL
pointer.

Your comment says you want to determine if list is NULL. You do that
with
     if (list == NULL) ...

>
>The method definition looks like...
>
>void listInsert(listNodePtr *list, int key, int value)

Since C passes by value, how do you expect the results of this
function to be available to the calling function. Anything you do to
list will disappear as soon as listInsert returns.

>
>I am assuming the body of the method is correct as this code
>was given to us to use by my Prof.
>
>Please help what am I doing wrong during my initialization?
>How do I use structs defined like the one above?

Your post indicates some misconceptions about C. Some may be
considered simply semantic (methods vs functions). Others seem to be
more basic, such as pointer syntax.

        When you declare a pointer (or typedef a pointer type), you use
the asterisk to indicate the variable or type is a pointer. When you
evaluate a pointer variable in your code, you do not use the asterisk
because in that context the asterisk means dereference the pointer.

        As others have mentioned, using typedef to create a pointer alias
is strongly not recommended.

Functions that manipulate linked lists usually use the return type to
send information back to the calling function. If you set the return
type of listInsert to struct ln* (or the equivalent listNode*), you
could then change head and list to this type and return list from the
listInsert.

If you really want to use pointer to pointer in listInsert (there are
times when this may be desirable), you should change head but pass
&head as the argument. list will still be a struct ln** but:

        When you evaluate list, you get the address of head, not the
contents of head.

        When you dereference list with *list, you are no longer attempting
to dereference a NULL pointer. list points to head and when you
dereference list you get the value in head which is NULL which makes
your if statement correct.

<<Remove the del for email>>



Relevant Pages

  • Re: Offset/alignement of structure members
    ... number of lists. ... all those tiny allocations of pared-down `struct node' objects, ... So you can safely feed a pointer to the ... The `links1' element is at offset zero, ...
    (comp.lang.c)
  • [Fwd: Re: >1024 connections in slapd / select->poll]
    ... I read your kqueue paper with great interest. ... The struct equeue describes the event list: ... for array indices there is a limit of 65535 events in an equeue. ... event lists and modifying them is essentially zero-cost. ...
    (Linux-Kernel)
  • Re: [PATCH] Driver Core patches for 2.6.7
    ... pointer to the struct class_simple that this device should be registered to. ... void device_unregister ... * controlling device power management will also be added. ... * A different set of lists than the global subsystem list are used to ...
    (Linux-Kernel)
  • [patch 06/14] split LRU lists into anon & file sets
    ... Split the LRU lists in two, one set for pages that are backed by ... unsigned long *scanned, int order, int mode, ... int mode, struct zone *z, ...
    (Linux-Kernel)
  • [PATCH -mm 06/16] split LRU lists into anon & file sets
    ... Split the LRU lists in two, one set for pages that are backed by ... unsigned long *scanned, int order, int mode, ... int mode, struct zone *z, ...
    (Linux-Kernel)