Почему указатели на функции, передаваемые в библиотеку (как обратный вызов), не вызывают ошибку сегментации при выполнении? - PullRequest
0 голосов
/ 06 марта 2019

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

1 Ответ

3 голосов
/ 07 марта 2019

Это не проблема, поскольку сама функция никогда не будет существовать в кадре стека.

Предположим, у вас есть этот код:

#include <stdio.h>

void (*fptr)(void);
int num;

void g(void) {
    printf("Hello, world!\n");
}

int f(void) {
    int a = 42;
    num = a;

    void (*p)(void) = &g;
    fptr = p;
}

int main(void) {
    f();

    printf("%d\n", num);
    fptr();
}

В f, мы устанавливаем оба значения fptr и num до значения локальной переменной.Если мы попытаемся сослаться на a или p после возвращения f, у нас возникнут проблемы, но мы никогда этого не сделаем.

fptr не содержит p;он содержит &g, который является просто константой, в которой находится функция g в памяти.И g продолжает существовать в этом месте после возврата f, потому что сама функция не является локальной переменной.

И это то, что происходит, когда вы устанавливаете обратный вызов;где-то в этой библиотеке находится переменная, которой присваивается адрес переданной вами функции.

...