2013-07-30 2 views
1

Есть некоторые функции, используя void * как их параметры, как передать в этом случае умный указатель?Как передать умный указатель на функцию как void *?

Например, у меня есть

gboolean callback(gpointer arg); // might delete arg when it finish 

A *mydata = new A(); 
gpointer parg = (gpointer)mydata; 
g_timeout_add(100, callback, parg); 

Что делать, если я использую смарт-указатель здесь:

std::shared_ptr<A> mydata(new A()); 

Как преобразовать его в арг из g_timeout_add(.., void*)?

+2

'mydata.get()'. – 0x499602D2

+1

Если обратный вызов удаляет ваш указатель, тогда у вас возникают проблемы. –

+3

Убедитесь, что вы никогда не передаете указатель на функцию, которая может удалить указатель. Когда умный указатель будет уничтожен, он также удалит указатель, который является неопределенным поведением. –

ответ

4

Предполагаю из вашего названия, что gpointer на самом деле void*. В этом случае я также предполагаю, что когда вы говорите might delete arg when it finish, вы действительно имеете в виду free(), потому что как только вы выбросили оригинальный тип, вы не можете гарантировать, что delete будет легальным.

В этом случае ни при каких обстоятельствах не следует использовать интеллектуальный указатель для перехода к вызову g_timeout_add, поскольку он потенциально может привести как к обратному вызову, так и к умному указателю как к удалению одной и той же памяти, а затем к неопределенному поведению.

Вам необходимо решить, кому принадлежит mydata: вызывающий, обратный вызов или общий доступ. Затем на основе этого вы можете реализовать код вызывающего/обратного вызова, чтобы правильно представлять семантику собственности.

+0

Спасибо. К сожалению, мне нужно явно называть 'delete' /' free' в этом случае, я думал, что могу как-то использовать интеллектуальный указатель, чтобы избежать потенциальной утечки памяти здесь. – Deqing

Смежные вопросы