#c #void-pointers
#c #указатели void
Вопрос:
Вызывающий в первый раз, долгое время слушающий. У меня есть вопрос о каком-то указателе void * и, похоже, я не могу найти объяснение, поэтому, возможно, кто-то здесь может пролить некоторый свет.
У меня есть функция-обработчик, где (среди прочего) Я объявляю указатель void и передаю его по ссылке в какую-либо другую функцию:
void some_handler(some args)
{
void * p_out_data;
some_other_function(amp;p_out_data);
// ... do some stuff with p_out_data after some_other_function stores an address
}
В some_other_function я выделяю некоторую память (сколько зависит от нескольких факторов), копирую в нее a_bunch_of_data и сохраняю его адрес в p_out_data, чтобы some_handler мог получить доступ к a_bunch_of_data:
void some_other_function(void * pp_out_data) // pp_out_data is the address of p_out_data
{
void * p = malloc(d_size);
memcpy(p, amp;a_bunch_of_data, d_size);
memcpy(pp_out_data, amp;p, sizeof(p));
}
Все это работает хорошо. Мой вопрос: почему единственный способ сохранить адрес памяти, возвращаемый malloc(), в p_out_data — это использовать memcpy? Я попытался напрямую сохранить адрес в разыменованном указателе:
*pp_out_data = malloc(d_size);
Но я получаю сообщение об ошибке о незаконном использовании указателя void. Я знаю, что существует множество правил для указателей void, поэтому я предполагаю, что здесь применяется конкретное?
Комментарии:
1. pp_out_data должен быть указателем на
void*
. Как вы пишете «указатель наvoid*
«?
Ответ №1:
Вы передаете указатель на указатель, поэтому определите функцию как таковую:
void some_other_function(void **pp_out_data)
{
void * p = malloc(d_size);
memcpy(p, amp;a_bunch_of_data, d_size);
*pp_out_data = p;
}
Комментарии:
1. Я вижу, что вы там сделали, но два косвенных обращения, вероятно, не идеальны для простой передачи адреса памяти. Смотрите мои комментарии выше.
2. Верно, в этом простом случае было бы предпочтительнее просто вернуть
void *
. Вы всегда можете опубликовать это как другой ответ, но я считаю, что мой ответ все еще поучителен.3. Да! Это то, что я искал. Спасибо!
4. Кроме того, возврат void * будет работать, но, я думаю, я слишком упростил проблему для публикации, поскольку я фактически возвращаю код состояния.
Ответ №2:
*pp_out_data
это не ваша переменная указателя; это данные, на которые указывает ваша переменная указателя.
Другими словами, вы уже разыменовали его.
Если вы ожидаете, что новый адрес будет передан из вашей функции через ваш pp_out_data
параметр, это не работает таким образом; адрес в pp_out_data
передается по значению.
return
вместо этого новый адрес из функции:
void* some_other_function(void* pp_out_data)
{
void* p = malloc(d_size);
memcpy(p, amp;a_bunch_of_data, d_size);
memcpy(pp_out_data, amp;p, sizeof(p));
return p;
}