2013-11-11 3 views
0

Здесь я буду использовать псевдо-пример, хотя я заметил это поведение в нескольких API-интерфейсах, таких как sqlite3 или windows.Многоуровневый указатель как аргумент C++

Say функция объявлена ​​следующим образом:

void Fu(some_identifier **ppBar); 

и я делаю это в моем коде:

some_identifier **ppFubar; 
    fu(ppFubar); 

Это мое понимание того, что это будет работать, и это действительно делает в моих собственных функций , Однако моя программа вылетает из-за переполнения буфера, когда я делаю это с некоторыми API.

Если я это сделать:

some_identifier *pFubar; 
    fu(&pFubar); 

все в порядке.

Do ppFubar и & pFubar не оценивает то же самое?

EDIT:

Конкретный пример будет (четвертый аргумент):

int sqlite3_prepare(
    sqlite3 *db,   /* Database handle */ 
    const char *zSql,  /* SQL statement, UTF-8 encoded */ 
    int nByte,    /* Maximum length of zSql in bytes. */ 
    sqlite3_stmt **ppStmt, /* OUT: Statement handle */ 
    const char **pzTail  /* OUT: Pointer to unused portion of zSql */ 
); 
+2

«некоторые API» могут потребовать от вас что-то выделить и передать его. –

+0

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

+2

Только если вы инициализируете ppFubar, чтобы указать на некоторый '* some_identifier'. Если нет, это просто неинициализированный висячий указатель. – rici

ответ

4

Ваше понимание является неправильным.

Если функция принимает параметр some_identifier **ppFubar;, она, вероятно, собирается что-то связать с объектом some_identifier где-то внутри его тела функции.

Если вы звоните по номеру some_identifier **ppFubar;, вы даете ему неинициализированный указатель, то есть указатель на мусор. Если функция что-либо делает с ней (например, она разыгрывает ее, один или два раза), вы сталкиваетесь с неопределенным поведением (скорее всего, это сбой).

Передайте правильно инициализированный указатель на функцию.

+0

Я отредактировал мой вопрос, чтобы добавить пример API. Для этой функции мне нужно инициализировать 'ppStmt' в' * sqlite3_stmt'? Я бы предположил, что API сделает «ppStmt» действительным указателем, нет? – smdufb

+0

@ user2731962 Вам нужна документация о том, что нужно передать функции. Без этого вы не сможете его использовать. Функция, которую вы опубликовали в качестве примера, очень плохо документирована, потому что она не говорит вам точно, что вам нужно отправить на нее. Это одна из причин, по которой использование API-указателей API является плохой идеей. –

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