2

What is the error in this code? Why i cant dereference the element the way I am trying it to.

#include<stdio.h>
typedef struct
{
    int value;
    struct node * left;
    struct node * right;
} node;

int main() {
    node* root,*temp;
    root = (node*) malloc(sizeof(node));
    root->value = 10;
    (root->left)= (node*) malloc(sizeof(node));
    (root->right)=(node*) malloc(sizeof(node));
    ((root->left)->value) =20;   // WHY AN ERROR HERE???
}   
phihag
  • 278,196
  • 72
  • 453
  • 469
user420878
  • 229
  • 1
  • 2
  • 7
  • 2
    Don't typedef the struct. It has a type already as a struct - all you're doing is making your code more complicated. –  Feb 06 '11 at 11:36
  • @Felice Pollano Apart from a sea of warnings: error: dereferencing pointer to incomplete type – phihag Feb 06 '11 at 11:37
  • 2
    @Blank Xavier Well, typedef allows you to omit the struct when you use it, so it can make code more easy to read. – phihag Feb 06 '11 at 11:38
  • 2
    @Phihag: it hides the underlying type. This is exactly what you want when and ONLY when all operations on the type occur through functions. In this case, since it IS a struct, and we USE it as a struct (e.g. "->"), then we need to KNOW it is a struct, so hiding its type is not useful. It places an additional burden on the reader, who has to remember the underlying type of every single typedef we have which is not function-operated-only. –  Feb 06 '11 at 11:42
  • @Blank Xavier: I understand your considerations, but a more readable code can also be very convenient as @phihag said. Moreover, the fact that we use -> on it is sufficient to know it's a struct... – jopasserat Feb 06 '11 at 11:49
  • @jHack: the present or absence of the keyword "struct", IMHO, does not contribute significantly to readability. I would also say if it -did-, would we not then have a case for using defines and typedefs to eliminate other keywords from the language? do you argue this should be so? –  Feb 06 '11 at 12:28
  • @jHack: one should not be in the position of having to observe the operaters used with a variable to determine its type. –  Feb 06 '11 at 12:29
  • @Blank Xavier: I agree with you that we should not replace every language keywords with typedefs or defines, but in some cases it really helps. I don't need to see the struct keyword in front of node, cause everybody knows it's not a scalar type. However, I dislike macros such as MAX(x, y), since I don't really know what they do and are not safe. Typedef inputs might not be evident when it's just used with C structures, but can imagine not having them with more complicated syntaxes such as function pointers for example? – jopasserat Feb 06 '11 at 12:49

2 Answers2

11

Your structure definition misses the typename that you reuse further. When you declare left and right field, the compiler does not know what struct node is. You need to declare that you structure is a node. This implies to change the typedef alias. See the correction hereafter, this compiles fine:

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

typedef struct node
{
        int value;
        struct node * left;
        struct node * right;
} Node;

int main() {
        Node* root,*temp;
        root = (Node*) malloc(sizeof(Node));
        root->value = 10;
        (root->left)= (Node*) malloc(sizeof(Node));
        (root->right)=(Node*) malloc(sizeof(Node));
        ((root->left)->value) =20;   /* no more errors */

        return 0;
}
jopasserat
  • 5,721
  • 4
  • 31
  • 50
  • still it says that the dereferencing pointer to incomplete type – user420878 Feb 06 '11 at 11:33
  • 2
    @user420878 Please make absolutely sure you're using exactly this code. Compiles fine here with gcc 4.3.2. Note that jHackTheRipper changed the name of your type from node to Node. Instead, you may want to replace struct node with struct node_its_a_struct or so – phihag Feb 06 '11 at 11:36
  • Strange... Which compiler are you using? It compiles fine for me on MacOS X (gcc 4.2.1) and Linux CentOS (gcc 4.1.2) with stringent flags: gcc -Wall -Wextra -ansi -pedantic -posix foo.c – jopasserat Feb 06 '11 at 11:37
  • @user420878: When somebody resolves your problem, you should accept their answer by clicking the tick under the answer's votes. You already asked 10 questions on this site and never rewarded any user for the time they gave to help you. Moreover, you now have enough reputation to [upvote answers](http://stackoverflow.com/privileges/vote-up), to indicate that a post is interesting. I encourage you to go back to the previous questions you asked and give some vote to the answers that helped you; more generally, I encourage you to read [the stackoverflow faq](http://stackoverflow.com/faq). – Luc Touraille Mar 11 '11 at 14:42
3

First of all, let me recommend to turn on all warnings. You'll see the first problem is with assigning root->left at all. You cannot reference the name established by typedef inside a struct definition. Instead, Use the struct name, like this:

typedef struct node_t {
    int value;
    struct node_t * left;
    struct node_t * right;
} node;
Community
  • 1
  • 1
phihag
  • 278,196
  • 72
  • 453
  • 469