0

ここでは疑似例を使用しますが、sqlite3 や windows などのいくつかの API でこの動作に気付きました。

関数が次のように宣言されているとします。

    void Fu(some_identifier **ppBar);

そして、私は自分のコードでこれを行います:

    some_identifier **ppFubar;
    fu(ppFubar);

これが機能することは私の理解であり、実際に私自身の機能で機能します。しかし、いくつかの API でこれを行うと、バッファ オーバーフローの後でプログラムがクラッシュします。

私がこれを行う場合:

    some_identifier *pFubar;
    fu(&pFubar);

すべて順調。

ppFubar と &pFubar はまったく同じものに評価されませんか?

編集:

具体例は次のようになります (4 番目の引数):

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 */
);
4

1 に答える 1

4

あなたの理解は間違っています。

関数がパラメーターを受け取る場合、関数本体内のどこかでオブジェクトsome_identifier **ppFubar;に関連する何かを実行する可能性があります。some_identifier

で呼び出すとsome_identifier **ppFubar;、初期化されていないポインター、つまりガベージへのポインターが渡されます。関数が何かを行う場合 (たとえば、1 回または 2 回逆参照する)、未定義の動作が発生します (ほとんどの場合、クラッシュします)。

正しく初期化されたポインターを関数に渡します。

于 2013-11-11T16:34:19.443 に答える