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代码行从 before移动my_function()到 AFTER my_function(),重新编译代码并运行它,printf语句显示第一次调用数据库的数据正确保存在 C 程序中,但第二次调用的数据不正确,并且printf第三次通话中的声明似乎没有做任何事情。

在编译和运行时没有报告错误或警告。

我在 C(或 OCILIB)方面没有那么丰富的经验,但对于那些有经验的人来说,是否有一个合乎逻辑的解释,代码中的位置如何return EXIT_SUCCESS与位于它之前的代码交互,从而导致这种情况?

在我的简单头脑中,我认为代码一次执行一行,所以如果代码工作到第 123 行(例如),对第 456 行代码的更改不应该影响到第 123 行的结果(例如,当比较更改前后到第 456 行时)。也许我错过了什么?

4

3 回答 3

2

另一种可能性是您的代码依赖于未初始化变量的值,并且通过return在调用之前添加myfunction()您正在更改编译器在内存中布置变量的方式。

例如,优化编译器可能会注意到对 的调用myfunction()由于 而无法访问return,因此它可能能够避免为myfunction()调用可能需要的临时变量留出空间。

确保您的编译器设置为警告使用未初始化的变量。

于 2012-04-06T02:33:48.003 回答
1

改写答案:

如果您的代码的行为与您描述的不同,则表明return调用之前的版本未在其可执行映像中包含您的函数(未使用的代码已被优化),这会改变内存布局。如果您有严重的内存管理问题,这可能会影响您的代码。

您是否尝试在第二批数据库活动之后重新打印第一批数据,以确保您仍然拥有您认为已成功读取的信息?您对检索到的信息的打印是否彻底和完整?

于 2012-04-06T02:10:47.033 回答
1

我猜您的printf陈述不会以换行符结尾;在这种情况下,输出直到main结束才会刷新。这允许同时my_function腐败stdout。使用换行符或者fflush我敢打赌这种明显的异常行为将会停止。

于 2012-04-06T02:22:09.867 回答