Ваша функция
void test(void **arg);
ожидает «указатель на указатель на void» , то есть адрес местоположения, который содержит другой адрес, указывающий на общие c данные.
Когда вы вызываете функцию, вы не передаете то, что она ожидает
int temp = 0;
test((void **)&temp);
Фактически &temp
- это адрес, указывающий на целое число. Но он ожидает адрес по адресу! Таким образом, когда внутри функции вы обращаетесь к ней дважды (каждая ссылка с помощью операторов *
означает «разрешение» одного адреса) во второй раз, когда вы пытаетесь получить доступ к адресу 0.
Чтобы исправить его, просто передайте test
указатель на указатель:
int temp = 0;
int *tempAddr = &temp; //tempAddr points to temp
test((void **)&tempAddr); //The type of the address of tempAddr is 'int **'
Вы на самом деле просили другое: вы явно просили исправить строку **((int **) arg) = foo;
.
Это не так просто, так как вы в настоящее время получаете недопустимый указатель на указатель, и нет способа сделать его действительным, просто изменив эту строку. Чтобы разобраться с этим, вам нужно изменить интерфейс test()
, как показано ниже:
#include <stdio.h>
void test(void *arg) { // changed 'void **' to 'void *'
int foo = 3;
*(int *)arg = foo; // only one level of dereferencing
}
int main(void) {
int temp = 0;
printf("%d\n", temp);
test((void *)&temp); // cast to 'void *' instead of 'void **'
printf("%d\n", temp);
return 0;
}