Что делает (освободите **), средний в C?

Я искал бы это, но честно я не буду знать, где запустить, потому что я не знаю то, чем это называют. Я видел, что переменные передали функциям как это:

myFunction((void**)&variable);

Который путает heck из меня, вызывают всех тех, выглядят знакомыми мне; я только что никогда не видел, что они соединяют как этот прежде.

Что это значит? Я - newb так чем меньше жаргона, тем лучше, Спасибо!

6
задан Jonathan Leffler 31 May 2010 в 03:50
поделиться

6 ответов

Это приведение к указателю на указатель void .

Вы часто наблюдаете это с такими функциями, как CoCreateInstance () в системах Windows.

ISomeInterface* ifaceptr = 0;
HRESULT hr = ::CoCreateInstance(CLSID_SomeImplementation, NULL, CLSCTX_ALL,
    IID_ISomeInterface, (void**)&ifaceptr);
if(SUCCEEDED(hr))
{
    ifaceptr->DoSomething();
}

Приведение преобразует указатель на указатель ISomeInterface в указатель на указатель void , чтобы CoCreateInstance () мог установить ifaceptr ] на допустимое значение.

Поскольку это указатель на указатель void , функция может выводить указатели любого типа в зависимости от идентификатора интерфейса (например, IID_ISomeInterface).

4
ответ дан 8 December 2019 в 12:18
поделиться

Это приводит к преобразованию & variable в void ** (то есть указатель на указатель на void ).

Например, если у вас есть что-то вроде

void myFunction(void** arg);

int* variable;

Это передает адрес переменной (это то, что делает унарный- & , он принимает адрес) в myFunction () .

1
ответ дан 8 December 2019 в 12:18
поделиться

void * - это «указатель на что угодно». void ** - это еще один уровень косвенного обращения - «указатель на указатель на что-либо». По сути, вы передаете это, когда хотите, чтобы функция возвращала указатель любого типа.

& variable принимает адрес переменной. переменная уже должна быть своего рода указателем, чтобы это работало, но, вероятно, это не void * - это может быть, скажем, int * , поэтому адрес приведет к int ** . Если функция принимает void ** , вам необходимо привести к этому типу.

(Конечно, он должен действительно вернуть объект правильного типа, иначе вызывающий код не сработает, когда попытается использовать его неправильно.)

9
ответ дан 8 December 2019 в 12:18
поделиться

Это указатель на указатель на переменную неопределенного типа. Все указатели имеют одинаковый размер, поэтому void * означает просто «указатель на что-то, но я понятия не имею, что это такое». void ** также может быть двумерным массивом неопределенного типа.

3
ответ дан 8 December 2019 в 12:18
поделиться

Переменная является указателем на что-то неопределенного типа (void). Оператор & возвращает адрес этой переменной, так что теперь у вас есть указатель на указатель на что-то. Поэтому указатель передается в функцию по ссылке. Функция может иметь побочный эффект, который изменит память, на которую ссылается этот указатель. Другими словами, вызов этой функции может изменить то, на что ссылается исходный указатель.

0
ответ дан 8 December 2019 в 12:18
поделиться

Разбирайте его по частям ...

myFunction принимает указатель на указатель типа void (что в значительной степени означает, что он может указывать на что угодно). Это можно было бы объявить примерно так:

myFunction(void **something);

Все, что вы передаете, должно иметь этот тип. Итак, вы берете адрес указателя и преобразуете его с помощью (void **), чтобы он стал пустым указателем. (По сути, лишая его всякого представления о том, на что он указывает - что в противном случае компилятор мог бы ныть.)

Это означает, что & переменная является адресом (& делает это) указателя, поэтому переменная является указателем. К чему? Кто знает!

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

#include <stdio.h>

int myInteger = 1;
int myOtherInt = 2;
int *myPointer = &myInteger;

myFunction(void **something){
    *something = &myOtherInt;
}

main(){
    printf("Address:%p Value:%d\n", myPointer, *myPointer);
    myFunction((void**)&myPointer);
    printf("Address:%p Value:%d\n", myPointer, *myPointer);
}

Если вы скомпилируете и запустите это, он должен дать следующий вид вывода:

Address:0x601020 Value:1
Address:0x601024 Value:2

Вы можете видеть, что myFunction изменила значение myPointer - что он мог сделать только потому, что ему был передан адрес указателя.

3
ответ дан 8 December 2019 в 12:18
поделиться