1

Linux ボックスで gcc -std=C89 スイッチを使用して C コードをプログラミングしています。この C コードは、 OCILIBライブラリによって呼び出される OCI ドライバを使用して、Oracle データベースと通信します。データベースから必要なデータをダウンロードした後、C プログラムは、多くの複雑な計算を実行する C 関数 (my_function) を呼び出します。プログラムの流れは次のようになります。

int main (void) {
    OCI_Connection *cn; 
    OCI_Statement  *st;
    OCI_Resultset  *rs; 
    ...
    /* FIRST CALL TO DB */
    OCI_Initialize(NULL, NULL, OCI_ENV_DEFAULT);
    cn = OCI_ConnectionCreate(...);
    st = OCI_StatementCreate(cn);
    OCI_Prepare(st, ...);
    OCI_Bindxxx(st, ...);
    OCI_Execute(st);

    printf(...); /* verify data retrieved from database is correct */

    /* SECOND CALL TO DB */
    OCI_Prepare(st, ...); /* different prepare stmt than above */
    OCI_Bindxxx(st, ...);
    OCI_Execute(st, ...);

    printf(...); /* verify data retrieved from database is correct */

    /* THIRD CALL TO DB */
    OCI_SetFetchSize(st, 200);
    OCI_Prepare(st, ...);
    OCI_Bindxxx(st, ...);
    OCI_Execute(st);
    rs = OCI_GetResultset(st);
    ...
    printf(...); /* verify data retrieved from database is correct */

    OCI_Cleanup();
    return EXIT_SUCCESS;

    my_function(...);
}

示されているようにプログラムを実行すると、printfステートメントはすべて、正しいデータがデータベースから C プログラムにダウンロードされたことを示します。ただし、my_function実行していません。

その後return EXIT_SUCCESS、コード行を beforemy_function()から AFTERmy_function()に移動し、コードを再コンパイルして実行すると、printfステートメントは、データベースへの最初の呼び出しからのデータが C プログラムに正しく保存されていることを示していますが、2 回目の呼び出しのデータは正しくありません。 、そしてprintf3 回目の呼び出しからのステートメントは何もしていないように見えます。

コンパイル時および実行時に報告されるエラーや警告はありません。

私はC(またはOCILIB)の経験が豊富ではありませんが、経験がある人にとって、コード内の配置がreturn EXIT_SUCCESSその前にあるコードと相互作用してこれを引き起こす方法について論理的な説明はありますか?

私の単純な考えでは、コードは一度に 1 行ずつ実行されると考えているため、コードが 123 行目まで機能する場合 (たとえば)、456 行目のコードを変更しても、123 行目までの結果には影響しないはずです (たとえば、456 行目への変更前と変更後を比較する場合)。おそらく私は何かを逃していますか?

4

3 に答える 3

2

もう 1 つの可能性は、コードが初期化されていない変数の値に依存しており、return呼び出す前に を追加するmyfunction()ことで、コンパイラが変数をメモリに配置する方法を変更していることです。

たとえば、最適化コンパイラは、 が原因で への呼び出しにmyfunction()到達できないことに気付くreturn場合があります。したがって、呼び出しに必要な一時変数用にスペースを確保しなくても済む場合がありmyfunction()ます。

初期化されていない変数の使用について警告するようにコンパイラが設定されていることを確認してください。

于 2012-04-06T02:33:48.003 に答える
1

書き直された答え:

コードの動作が説明と異なる場合は、呼び出し前のバージョンの実行可能イメージに関数が含まれていないことを示唆しておりreturn(未使用のコードは最適化されています)、メモリ レイアウトが変更されます。重大なメモリ管理の問題がある場合、これはコードに影響を与える可能性があります。

2 回目のデータベース アクティビティの後、最初のデータを再印刷して、正常に読み取れたと思っていた情報がまだ残っていることを確認しましたか? 検索された情報の印刷は完全で完全でしたか?

于 2012-04-06T02:10:47.033 に答える
1

あなたのprintfステートメントは改行で終わっていないと思います。この場合、出力は最後までフラッシュされませんmain。これにより、その間my_functionに破損する可能性があります。stdout改行を使用するかfflush、この明らかに異常な動作が停止するに違いありません。

于 2012-04-06T02:22:09.867 に答える