views:

57

answers:

5

What am I doing wrong here ?

/*
 * Consider the following pseudo code !
 */
typedef struct foobar {
    unsigned char id, count;
    struct foobar *child;
} foobar;

foobar root = (foobar *) malloc( sizeof(struct foobar) );
root->child = (foobar *) malloc( sizeof(struct foobar) );

root->count++;
root->child[0].id = 1;

root->count++;
root->child[1].id = 2;

root->count++;
root->child[3].id = 3;

root->child[0].child = (foobar *) malloc( sizeof(struct foobar) );

root->child[0].child[0].count++;
root->child[0].child[0].id = 4;

root->child[1].child = (foobar *) malloc( sizeof(struct foobar) );
root->child[0].child[0].count++;
root->child[1].child[0].id = 5;

root->child[0].child[0].count++;
root->child[1].child[1].id = 6;

/* and so on */

/*
 * Function to search for an ID inside the tree,
 * it should call itself in order to go deeper into
 * the childs, but taht's not implemented here
 */
foobar *search( unsigned char id, foobar *start_node = NULL );
foobar *search( unsigned char id, foobar *start_node ) {
    if( start_node == NULL ) {
        unsigned char x;
        for( x = 0; x < root->count; x++ ) {
            if( root->child[ x ].id == id ) {
                foobar *ptr = &root->child[ x ];
                /* If I call ptr->id now, it will return the correct value */
                return &ptr;
            }
        }

    } else { /* not implemented */ }
}

/* Search the array for and ID */
foobar **ptr = this->search( 1 );
/* If I call ptr->id now, it will return memory garbage */
A: 

You're returning the address of the pointer you've retrieved. You should be returning the pointer itself.

Anon.
+1  A: 

You only malloc memory for one child, but try to set the id for up to 4 children.

It should be like this:

root->child = (foobar *) malloc( sizeof(struct foobar) * 4 );
Alexander Kjäll
+2  A: 

root has 4 children (as you access root->child[3]), so you must allocate enough memory:

root->child = (foobar *) malloc( sizeof(struct foobar) * 4 ); //at least 4

Also, you should return the foobar pointer itself, and not a pointer to it (i.e. return ptr; instead of return &ptr;.

adamk
I've corrected the code and now I'm returning only "return ptr"; the memory is still garbaged. How can I return a valid pointer pointing to the memory address of root->child[ x ] so it can be used later on outside the function. The ideia is to do a search for the id and return the object that contains that id.
Joao
Did you remember to change `foobar **ptr = this->search( 1 );` to `foobar *ptr = this->search( 1 );` too?
adamk
Yes.. also did that. I'm very newb to C but if a function returns a pointer to the memory address of root->child[ x ] (root is a var at global level), the memory addr would be valid either inside or outside the function.. correct ?
Joao
@Joao: You are correct. The code should work - try printing the value of ptr and ptr->id inside `search` and after it returns - it should be the same value for both printouts.
adamk
+1  A: 

You are returning the address of a local variable from function search (return &ptr;). This object will be destroyed as soon as the search function is exited. Trying to use this memory location from outside the function will result in undefined behavior.

Naveen
I've corrected the code and now I'm returning only "return ptr"; the memory is still garbaged.How can I return a valid pointer pointing to the memory address of root->child[ x ] so it can be used later on outside the function.The ideia is to do a search for the id and return the object that contains that id.
Joao
A: 

I was doing a couple things wrong.. in the code above the lines:

foobar *ptr = &root->child[ x ];
return &ptr;

Should be changed simply to return &root->child[ x ];, this will return a pointer to the memory addr of root->child[ x ].

The line foobar **ptr = this->search( 1 ); will become foobar *ptr = this->search( 1 );, this will allow to access the struct properties using the . char; -> cannot be used and will output garbage. Correct usage example: (*ptr).description.

Many thanks to adamk !

Joao
You are mistaken - `(*ptr).description` is *exactly the same* as `ptr->description`.
caf