Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Забавный макрос container_of 
:(
    Опции темы
newbie2009
Дата 16.8.2013, 04:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 161
Регистрация: 8.2.2009

Репутация: нет
Всего: нет



Доброго времени суток.

Наткнулся на такую вот статью - http://linuxkernel51.blogspot.kr/2011/02/h...ks-example.html
Решил попробовать для своих целей, но не могу понять почему оно не работает в моем случаи и хотелось бы понять, как оно вообще в целом работает. Подскажите пожайлуста:
Код

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

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

#define container_of(ptr, type, member) ({            \
 const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
 (type *)( (char *)__mptr - offsetof(type,member) );})

struct vma_area {
    struct mm_struct *mm;
};

struct mm_struct { // test1
     struct vma_area *vma;
};

struct task_struct { // test2
     int pid;
     struct mm_struct *mm;
};

int main()
{
    struct task_struct *ts = malloc(sizeof(struct task_struct));
    if (ts == NULL) {
        return 1;
    }

    ts->pid         =   1245;
    ts->mm          =   malloc(sizeof(struct mm_struct));
    ts->mm->vma     =   malloc(sizeof(struct vma_area));
    ts->mm->vma->mm =   ts->mm;

//    struct vma_area *my_vma = ts->mm->vma;

    struct mm_struct *my_mm = &ts->mm; /*&my_vma->mm;*/

    struct task_struct *new_ts = container_of(my_mm, struct task_struct, mm);

    printf("pid = %d\n", new_ts->pid);

 return EXIT_SUCCESS;
}


Собственно если я расскоментирую вот эту часть *&my_vma->mm;*/, то я уже pid получу не верный, почему? И почему если я вместо  struct mm_struct *my_mm = &ts->mm;  напишу  struct mm_struct *my_mm = ts->mm; , то нефига опять работать не будет, там ведт вроде не должно быть - & ?

Это сообщение отредактировал(а) newbie2009 - 16.8.2013, 04:29
PM MAIL   Вверх
mes
Дата 16.8.2013, 09:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



проблема в указателе, вам нужен адрес поля mm (т.е. указатель на указатель), а не того обьекта, на который это поле указывает..



--------------------
PM MAIL WWW   Вверх
newbie2009
Дата 16.8.2013, 10:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 161
Регистрация: 8.2.2009

Репутация: нет
Всего: нет



Спасибо, в этом я разобрался + вы подвердили.

Я не множко переписал тестовое приложение:
Код

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

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

#define container_of(ptr, type, member) ({            \
 const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
 (type *)( (char *)__mptr - offsetof(type,member) );})

struct vma_area {
    struct mm_struct *mm;
};

struct mm_struct { // test1
    struct vma_area *vma;
};

struct task_struct { // test2
     int pid;
     struct mm_struct *mm;
};

int main()
{
    struct task_struct *TS = malloc(sizeof(struct task_struct));
    if (TS == NULL) {
        return 1;
    }

    TS->pid = 1245;

    struct vma_area *VMA = malloc(sizeof(struct vma_area));
    struct mm_struct *MM = malloc(sizeof(struct mm_struct));

    TS->mm = MM;
    VMA->mm = MM;
    MM->vma = VMA;
    //------------------------------------------------------------------------------------------------------------
    struct task_struct *my_ts = container_of(&VMA->mm, struct task_struct, mm);
    if (my_ts == TS) {
        printf("TSs is equal\n");
    }

    return EXIT_SUCCESS;
}


Я так понимаю в этом случаи я не смогу получить используя VMA->mm структурку task_struct? Или я опять не правильно использую макрос? Исходя из того, как этот макрос работает я так понял у меня не выйдет сделать. Или я не прав?
PM MAIL   Вверх
xvr
Дата 16.8.2013, 11:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(newbie2009 @  16.8.2013,  10:30 Найти цитируемый пост)
Я так понимаю в этом случаи я не смогу получить используя VMA->mm структурку task_struct?

Не сможете

Цитата(newbie2009 @  16.8.2013,  10:30 Найти цитируемый пост)
Исходя из того, как этот макрос работает я так понял у меня не выйдет сделать.

Угу, это принципиально невозможно. container_of позволяет перемещаться внутри структуры, имея адрес какого то ее поля. Но он никоим образом не может перескачить из одной структуры в совершенно другую, даже если в них есть поля с одинаковым содержимым (это ваш MM)

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1139 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.