Как я могу вернуть указатель на элемент внутри массива структур? - PullRequest
1 голос
/ 18 августа 2010

Что я здесь не так делаю?

/*
 * 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 */

Ответы [ 5 ]

2 голосов
/ 18 августа 2010

root имеет 4 дочерних (при доступе к root-> child [3]), поэтому вы должны выделить достаточно памяти:

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

Кроме того, вы должны вернуть сам указатель foobar, а не указательк нему (т.е. return ptr; вместо return &ptr;.

1 голос
/ 18 августа 2010

Я сделал пару вещей неправильно .. в коде над строками:

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

Должно быть изменено просто на return &root->child[ x ];, это вернет указатель на адрес памяти root->child[ x ].

Строка foobar **ptr = this->search( 1 ); станет foobar *ptr = this->search( 1 );, это позволит получить доступ к свойствам структуры с помощью . char; -> не может использоваться и будет выводить мусор. Пример правильного использования: (*ptr).description.

Большое спасибо adamk !

1 голос
/ 18 августа 2010

Вы возвращаете адрес локальной переменной из функции search (return &ptr;).Этот объект будет уничтожен, как только выйдет функция search.Попытка использовать эту область памяти извне функции приведет к неопределенному поведению.

1 голос
/ 18 августа 2010

Вы используете память malloc только для одного ребенка, но попробуйте установить идентификатор для максимум 4 детей.

Должно быть так:

root->child = (foobar *) malloc( sizeof(struct foobar) * 4 );
1 голос
/ 18 августа 2010

Вы возвращаете адрес указателя, который вы получили.Вы должны возвращать сам указатель.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...