WedX - журнал о программировании и компьютерных науках

Сохранение указателя функции, переданного аргументом

У меня есть следующие объявления:

typedef void (*foo)(int op, int arg1, int arg2);
void goo(foo f);
{
  BODY;
}

и я хочу сохранить функцию f, переданную goo в моем коде, но естественный способ изменить тело и добавить глобальную переменную foo (я не могу изменить определение goo, но я могу редактировать тело):

foo _f;
void goo(foo f);
{
  _f = f;
}

делает segfaults. Буду благодарен за любые подсказки.

c
25.02.2014

  • Я думаю, что это задание должно работать. Назначение указателя не должно вызывать ошибки. Ваша проблема, вероятно, в чем-то другом. 25.02.2014
  • Действительно, проверьте, не является ли f NULL (или мусором), когда оно передается goo. 25.02.2014
  • честно говоря, я думаю, что вина заключается в условности вашего кода. По соглашению, с примерами функций вы используете «foo» и «bar», а не «goo». Когда вы не следуете соглашениям, это делает код очень трудным для чтения и понимания, поэтому я думаю, что если вы сделаете эти настройки, ошибку будет легче увидеть. 25.02.2014
  • pastebin.com/tafBQBEa Хорошо, вы оба частично правы, посмотрите на ссылку, почему вызов goo работает отлично, но page_sim_init делает segfaults? 25.02.2014
  • @Baranovskiy Вызывает ли page_sim_init ошибку сегментации, даже если вы используете те же аргументы для функции обратного вызова, что и в goog (т.е. callback(1,1,1))? 25.02.2014
  • Действительно, я уверен в правильности обратного вызова. 25.02.2014
  • Ошибка seg происходит в строке, где вызывается обратный вызов в page_sim_init, вы действительно уверены? Причиной проблемы может быть одно из других ваших заданий. 25.02.2014
  • Объект функции обратного вызова не существует. 25.02.2014

Ответы:


1

изменить На основе вашего полного кода вы должны изменить имя функции callback() в test.c на что-то другое, кроме "callback", поскольку вы уже определили символ в pagesim.c. Я сделал это редактирование, и программа заработала нормально.


Вот тест, который компилируется и запускается, возможно, вы сможете определить свою ошибку на основе этого:

#include <stdio.h>
typedef void (*foo)(int op, int arg1, int arg2);

foo _f;

void goo(foo f)
{
    _f = f;
    _f(1, 2, 3);
}

void testfxn(int op, int arg1, int arg2) {
    printf("%d %d %d", op, arg1, arg2);
}

void main() {
    goo(testfxn);
}
25.02.2014
  • Посмотрите на последний комментарий под основным постом. 25.02.2014

  • 2

    Из кода, который вы вставили, где вы определяете фактическое определение функции типа

    void func(int op, int arg1, int arg2)
    

    Ошибка сегмента исходит от goo(), вы видите вывод от printf(), но следующий вызов callback2() генерирует ошибку сегмента. callback2 — это указатель на функцию, но он не указывает ни на какую фактическую функцию.

    вы должны определить функцию

    void func(int op, int arg1, int arg2)
    {
         printf("%d %d %d\n", op, arg1, arg2);
    }
    

    затем вы вызываете goo() и page_sim_init() как

    goo(func);
    page_sim_init(page_size, mem_size, addr_space_size,
                        strategy, max_concurrent_operations, func);
    
    25.02.2014
  • Я не знаю, о каком типе вы говорите. В начале я попытался минимизировать пример, поэтому, если вы имеете в виду typedef void (*foo)(int op, int arg1, int arg2), то это typedef void (*pagesim_callback)(int op, int arg1, int arg2). Goo работает исправно, печатает все, что положено. Ошибка сегментации при вызове page_sim_init. Структура callback2 проста как один printf. 25.02.2014
  • @Baranovskiy из кода, который вы вставили. Вы напрямую передаете callback в goo(), но callback еще не инициализирован, чтобы указывать на какую-либо реальную функцию. Это недопустимый указатель функции. Попробуйте поставить printf("GOO\n"); после строки callback2(1,1,1);, вы увидите ошибку сегмента перед сообщением. 25.02.2014
  • Я пометил код вырезания на 43-й строке '[...]' (посмотрите, там тоже пока нет включений). 25.02.2014
  • @Baranovskiy Можете ли вы опубликовать код инициализации callback? Кроме того, почему вы так уверены, что ошибка сегмента происходит от callback в page_sim_init? 25.02.2014
  • pastebin.com/g8jgrbCa здесь весь код, segfault выполняется при назначении callback = _callback. 25.02.2014
  • у вас есть глобальная переменная callback, а также функция callback, при компиляции компилятор не выдал вам никакого предупреждения? вы можете попробовать изменить функцию callback на другое имя и проверить? 25.02.2014
  • Новые материалы

    Как создать диаграмму градиентной кисти с помощью D3.js
    Резюме: Из этого туториала Вы узнаете, как добавить градиентную кисть к диаграмме с областями в D3.js. Мы добавим градиент к значениям SVG и применим градиент в качестве заливки к диаграмме с..

    Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
    Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

    Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
    В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..


    Для любых предложений по сайту: [email protected]