Проблемы с пониманием использования указателя void (* fptr) (void) в массиве void - PullRequest
0 голосов
/ 07 марта 2019

У меня проблемы с пониманием кода программы на C, которая предположительно уязвима.

У нас есть это определение typedef void (*fptr)(void);, и я оставляю приведенный выше частичный код.У меня нет особых проблем с пониманием инструкции fptr p = pat_on_back;, которая просто определяет указатель fptr, который указывает на функцию, которая никогда не выполняется, потому что эта инструкция просто определяет и инициализирует указатель (верно?).

Моя проблема в понимании инструкции fptr ptrs[3] = { NULL, get_wisdom, put_wisdom };.Почему эта инструкция работает, когда тип fptr явно используется для объявления и инициализации массива void?Разве не нужно просто получить один параметр void?

Кстати, функции get_wisdom () и put_wisdom () принимают и возвращают void.Эта небольшая программа предназначена для заполнения и печати простого связанного списка символов, называемого «мудрость».Функции get_wisdom () и put_wisdom () делают именно то, что, по-видимому, делает.

char greeting[] = "Hello there\n1. Receive wisdom\n2. Add wisdom\nSelection >";
char prompt[] = "Enter some wisdom\n";
char pat[] = "Achievement unlocked!\n";
char secret[] = "secret key";

typedef void (*fptr)(void);

void pat_on_back(void) {
  write(outfd, pat, sizeof(pat));
  return;
}

void put_wisdom(void) {
  . . .
}

void get_wisdom(void) {
  . . .
} 

fptr  ptrs[3] = { NULL, get_wisdom, put_wisdom };

int main(int argc, char *argv[]) {

  while(1) {
      char  buf[1024] = {0};
      int r;
      fptr p = pat_on_back;
      r = write(outfd, greeting, sizeof(greeting)-sizeof(char));
      if(r < 0) {
        break;
      }
      r = read(infd, buf, sizeof(buf)-sizeof(char));
      if(r > 0) {
        buf[r] = '\0';
        int s = atoi(buf);
        fptr tmp = ptrs[s];
        tmp();
      } else {
        break;
      }
  }

  return 0;
}

1 Ответ

1 голос
/ 07 марта 2019
typedef void (*fptr)(void);

Определяет тип fptr как указатель на функцию, которая возвращает значение указанного типа (void) и требует указанных параметров (void)

fptr  ptrs[3] = { NULL, get_wisdom, put_wisdom };

Определяет ptrs как вектор из 3 элементов, каждый из которых является указателем на один функция, которая имеет void в качестве параметра (что угодно) и возвращает void.

  • ptrs [0] = NULL ; Первый указатель указывает на NULL.
  • ptrs [1] = get_wisdom ; Второй указатель указывает на функцию «get_wisdom».
  • ptrs [2] = put_wisdom ; третий указатель указывает на функцию "put_wisdom".
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...