Thread: I hate pointers or Pointer Issues

  1. #1
    Registered User
    Join Date
    Sep 2009
    Posts
    17

    Unhappy I hate pointers or Pointer Issues

    6 programs in and I still am having issues with pointers. I'll attach the code I have below. Suffice to say I am having issues with pointers. I'm using CodeBlocks IDE. In line 9 of my doublerotateright I get a requet for a member error and in line 11 incompatible type argument. I believe I have declared the functions correctly, they needed to return the struct node. Thanks for any insight, I'm going to continue to google and dig till I find the errors of my way(or code).

    <edit>
    I've figured out a couple and changed the code to match. still having an issue with incompatible type argument in line 11 of doublerotateright, which is an error that affects doublerotateleft as well.



    Code:
    #include "prog6.h"
    
    int main(int argc, char *argv[]){
    
        FILE *infile;
    
        infile = fopen("prog5.in", "r");
    
        struct node *current;
    
        current = NULL;
    
        float num;
    
        while(!feof(infile)){
    
            fscanf(infile, "%f", &num);
    
            insertnode(&current, &num);
    
            InOrderPrint(&current);
    
        }/*while(!feof(infile)){...*/
    
        fclose(infile);
    
        return 0;
    
    } /*int main(int argc, char *argv[]){...*/
    Code:
    
    #include <stdio.h>
    #include <stdlib.h>
    
    struct node {           /*Node Structure, each node has an floating point variable, an integer height, and a
                            pointer to the the left child, right child, and parent nodes*/
    
            float *num;
            struct node *left_child;
            struct node *right_child;
            struct node *parent;
            int *node_height;
    
    };
    
    struct node insertnode(struct node **, float *);
    struct node SingleRotateLeft(struct node **);
    struct node DoubleRotateRight(struct node **);
    struct node SingleRotateRight(struct node **);
    struct node DoubleRotateRight(struct node **);
    
    void InOrderPrint(struct node **);
    Code:
    #include "prog6.h"
    
    struct node insertnode(struct node **current, float *num){
    
        struct node *new = (struct node*)malloc(sizeof(struct node));
    
        if(new != NULL){
    
            (*new).num = num;
    
            if(*current == NULL){
    
                *current = new;
                (**current).node_height = 0;
                (**current).left_child = NULL;
                (**current).right_child = NULL;
    
            } /*if(*current == NULL){...*/
    
            else if(num < (**current).num){
    
                    (**current).left_child = insertnode(**current.left_child, num);
    
                    if((**current).left_child.node_height - (**current).right_child.node_height == 2){
                        if( num > (**current).right_child.num )
                            *current = SingleRotateLeft(*current);
                        else
                            *current = DoubleRotateLeft(*current);
    
                    }/*if((**current).right_child.node_height - (**current).left_child.node_height == 2){...*/
    
            else if(num > (**current).num){
    
                    (**current).right_child = insertnode(&(**current).right_child, num);
    
                    if((**current).right_child.node_height - (**current).left_child.node_height == 2){
    
                        if( num > (**current).right_child.num )
                            *current = SingleRotateWithRight(*current);
                        else
                            *current = DoubleRotateWithRight(*current);
    
                    }/*if((**current).right_child.node_height - (**current).left_child.node_height == 2){...*/
    
                }/*else if(num > (**current).num){...*/
    
            }/*else if(num < (**current).num){...*/
    
            if((**current).left_child.node_height > (**current).right_child.node_height)
    
                (**current).node_height = (**current).left_child.node_height + 1;
    
            else
    
                (**current).node_height = (**current).right_child.node_height + 1;
    
        } /*if(new != NULL){...*/
    
    } /*void insertnode(struct node **current, float *num){...*/
    Code:
    
    #include "prog6.h"
    
    struct node DoubleRotateLeft(struct node **current){
    
        (**current).left_child = SingleRotateRight(&(*current).left_child);
        return SingleRotateLeft(current);
    
    }/*struct node DoubleRotateLeft(struct node **current){...*/
    Code:
    
    #include "prog6.h"
    
    struct node DoubleRotateRight(struct node **current){
    
        (**current).right_child = SingleRotateLeft(&(*current).right_child);
        return SingleRotateRight(current);
    
    }/*struct node DoubleRotateRight(struct node **current){...*/
    Code:
    #include "prog6.h"
    
    void InOrderPrint(struct node **current){
    
        if((**current).left_child != NULL){
    
            InOrderPrint(&(**current).left_child);
    
        printf("%f, ", (**current).num);
    
        if((**current).right_child != NULL){
    
            InOrderPrint(&(**current).right_child);
    
    }/*struct node DoubleRotateRight(struct node **current){...*/
    Last edited by bolivartech; 11-13-2009 at 04:34 PM. Reason: more changes in code

  2. #2
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    highlight where is the problem. The function you mention doesnt have 9 or 11 lines

  3. #3
    Registered User
    Join Date
    Sep 2009
    Posts
    17
    Will do! I'll do it above so the thread doesn't get too long.

    The red is the incompatible types in assignment.

    The DarkOrange is the request for member in something not a structure or union

    I have quite a few of those, they are the only error in my singlerotationleft and right
    Last edited by bolivartech; 11-13-2009 at 04:34 PM.

  4. #4
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    There are a number of issues here, and I probably won't hit them all; but I will note some basic problems.

    In DoubleRotateRight():
    Code:
    (**current).right_child = SingleRotateLeft(&(*current).right_child);
    First, are you aware that current->right_child is the same as (*current).right_child? It will make your code cleaner to use the -> method where appropriate.

    That's not a real problem, though, just a stylistic issue. One real problem is that SingleRotateLeft() returns a "struct node". (**current).right_child is a "struct node *". These are incompatible types.

    In insertnode():
    Code:
    *current = SingleRotateLeft(*current);
    *current is a "struct node *". SingleRoteLeft()'s argument is "struct node **". Again, incompatible.

    Also in insertnode():
    Code:
    (**current).left_child = insertnode(**current.left_child, num);
    Surely you mean (**current).left_child in the function call. This would be the source of a "request for member in something not a struct" error.

    In InOrderPrint():
    Code:
    printf("%f, ", (**current).num);
    (**current).num is a float*. %f expects a float (actually a double, but due to one of C's rules it's OK to pass a float).

    I would recommend trying to make a simple linked list to practice using pointers. Problems will be easier to find in easier code and, hopefully, you'll gain a better understanding of how things work.

  5. #5
    Registered User
    Join Date
    Sep 2009
    Posts
    17
    Alright that makes sense. This was my first time using a struct for the return type and I wasn't sure how to declare it correctly. I knew I wasn't wanting to return anything but a pointer to the object. I'm still having a problem with getting the node_height and num member though. Is it possible to get the member or a member?

  6. #6
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    You can make your life easier and
    Code:
    typedef struct * node nodePtr;
    Then you can have
    Code:
    struct node insertnode(nodePtr *current, float *num)
    and inside insertnode you won't have to worry about ** and mixing single and double asterisk. Typedef makes life easier

  7. #7
    Registered User
    Join Date
    Sep 2009
    Posts
    17
    I may have figured it out thinking back you what you said about my function call

    (*(**current).left_child).node_height that looks horrible but it seems to work. I derefernce current twice, get the left_child member, derefernce the member (which is another node) and get the node_height member of the left_child node.

  8. #8
    Registered User
    Join Date
    Sep 2009
    Posts
    17
    I don't think we have studied typedef. If we have I must have missed it...

  9. #9
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by C_ntua View Post
    You can make your life easier and
    Code:
    typedef struct * node nodePtr;
    Then you can have
    Code:
    struct node insertnode(nodePtr *current, float *num)
    and inside insertnode you won't have to worry about ** and mixing single and double asterisk. Typedef makes life easier
    A typedef itself only reduces the number of stars needed for each declaration, so it has little impact here. Might be safer to wait until he's taught those.
    The best thing to do is to reduce any unnecessary double-pointers to single pointers.
    You only need a double-pointer where you are going to modify the pointer passed in. This means that the function InOrderPrint can be changed to just a single pointer right now.

    Beyond that, the rest of the functions can also be reduced to single pointers for the most part, by adding a couple more lines. At the top of each function:
    Code:
    node *currPtr = *current;
    Then since currPtr is a single pointer, you can use the arrow notation:
    Code:
                currPtr->node_height = 0;
                currPtr->left_child = NULL;
                currPtr->right_child = NULL;
    And before the function exits, to set your out pointer parameter, you do:
    Code:
    *current = currPtr;
    This is both a readability optimisation and a performance optimisation, as the generated assembly code will no longer have to do a double-dereference upon each usage.
    Last edited by iMalc; 11-13-2009 at 06:46 PM.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  10. #10
    Registered User
    Join Date
    Nov 2009
    Location
    Maryland, USA
    Posts
    46
    Quote Originally Posted by bolivartech View Post
    Code:
                *current = new;
    I had to look at that line for a number of seconds before I remembered we were talking C, not C++.

    It does not violate any rule to use a C++ reserve word (like new) as a variable in C, but it causes problems for developers who view the code if they jump back and forth between languages, as I do.

    Just mentioning.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 04-04-2009, 03:45 AM
  2. Returning pointer to array of pointers problem
    By jimzy in forum C Programming
    Replies: 15
    Last Post: 11-11-2006, 06:38 AM
  3. Pointers, arithmetic, and order of operation.
    By Aerie in forum C Programming
    Replies: 4
    Last Post: 04-19-2005, 07:35 AM
  4. Struct *** initialization
    By Saravanan in forum C Programming
    Replies: 20
    Last Post: 10-09-2003, 12:04 PM
  5. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM