glib2.0 / Ocilib - GTree在搜索时有时会插入“ð-X”/ Secfault

时间:2013-12-18 09:07:59

标签: c glib

我正在尝试从oracle中将值插入到GTree中。它有时会失败。值OCI_GetString (rs, 1)是“111,333,4”,但树插入“ð-X”。我可以修理吗?或者是否有任何经过测试的替代实施bbt,你可以推荐吗?
我尝试插入值lke this:

int buildQotHash(GTree* tree, char (*str)[3000])
{
    OCI_Connection* cn;
    OCI_Statement* st;
    OCI_Resultset* rs;
    if (!OCI_Initialize(err_handler, NULL, OCI_ENV_DEFAULT))
        return EXIT_FAILURE;

    cn = OCI_ConnectionCreate( "db", "user",  "passwd", OCI_SESSION_DEFAULT);
    st = OCI_StatementCreate(cn);

    OCI_ExecuteStmt(st, "select field1 <cut>, field18  from table");

    rs = OCI_GetResultset(st);
    int i = 1;
    int j = 0;
    while (OCI_FetchNext(rs))
    {

      tic *t         = malloc(sizeof(tic))  ;

      t->qotId           = OCI_GetInt    (rs,  2);
      t->close           = OCI_GetFloat  (rs,  3);
      if (OCI_GetDate(rs, 4) != NULL) OCI_DateToText(OCI_GetDate(rs, 4), "DD.MM.YYYY HH24:MI", 19, t->closeTs );
      t->open            = OCI_GetFloat  (rs,  5);
      t->high            = OCI_GetFloat  (rs,  6);
      t->low             = OCI_GetFloat  (rs,  7);
      t->volume          = OCI_GetFloat  (rs,  8);
      t->ask             = OCI_GetFloat  (rs,  9);
      if (OCI_GetDate(rs, 10) != NULL) OCI_DateToText(OCI_GetDate(rs, 10), "DD.MM.YYYY HH24:MI", 19, t->askTs );
      t->askVolume       = OCI_GetFloat  (rs, 11);
      t->bid             = OCI_GetFloat  (rs, 12);
      if (OCI_GetDate(rs, 13) != NULL) OCI_DateToText(OCI_GetDate(rs, 13), "DD.MM.YYYY HH24:MI", 19, t->bidTs );
      t->bidVolume       = OCI_GetFloat  (rs, 14);
      t->realClose       = OCI_GetFloat  (rs, 15);
      if (OCI_GetDate(rs, 16) != NULL) OCI_DateToText(OCI_GetDate(rs, 16), "DD.MM.YYYY HH24:MI", 19, t->realCloseTs );
      t->settle          = OCI_GetFloat  (rs, 17);
      if (OCI_GetDate(rs, 18) != NULL) OCI_DateToText(OCI_GetDate(rs, 18), "DD.MM.YYYY HH24:MI", 19, t->settleTs );
      const char *tri = OCI_GetString (rs,  1);
      g_tree_insert(tree,(gpointer *) tri, t);
      sprintf(str[j]+strlen(str[j]),"&ik%d=%s", i, tri);
      //i= (i > 99) ? i++ : 0;
      i > 99 ? j++ : j;
      i++;
      if(i>100)i=1;
    }

    OCI_Cleanup();

    return EXIT_SUCCESS;

}

除此之外,我在搜索时得到了secfaul。

我像这样初始化树:

  GTree* t = g_tree_new((GCompareFunc)g_ascii_strcasecmp);

  char subStr[8][3000];
  buildQotHash(t, subStr);

我在init之后遍历树时得到键值对:

gboolean iter_all(gpointer key, gpointer value, gpointer data) {
 ticP tp = (ticP) value;
 printf("%s %s\n", (char *)key, tp->closeTs);
 return FALSE;
}

g_tree_foreach(t, (GTraverseFunc)iter_all, NULL);

这一行以secfault结束:

 if( (triP!=NULL) &&( (value = g_tree_lookup(tree, (gpointer *)triP) )!= NULL)  ) fillFields((ticP)value, p);

在调试器中,我看到:

   (gdb) print tree
    $20 = (GTree *) 0x51c6c0
    (gdb) print triP
    $21 = 0x5ef6a0 "89680,222,402"
    (gdb) print (gpointer *)triP
    $22 = (gpointer *) 0x5ef6a0
    (gdb) print  g_tree_lookup(tree, (gpointer *)triP)

    Program received signal SIGSEGV, Segmentation fault.
    0x00002aaaaac10800 in ?? () from /opt/gnome/lib64/libglib-2.0.so.0
    The program being debugged was signaled while in a function called from GDB.
    GDB remains in the frame where the signal was received.
    To change this behavior use "set unwindonsignal on".
    Evaluation of the expression containing the function
    (g_tree_lookup) will be abandoned.
    When the function is done executing, GDB will silently stop.

1 个答案:

答案 0 :(得分:1)

如果没有能够运行代码(我不打算安装Oracle),很难真正说明出现了什么问题,但是判断你将OCI_GetString的返回值分配给了const char*,它可能归图书馆所有。我的猜测是,只要你调用OCI_FetchNext,值就会改变(或释放相关的内存)。如果我是你,我会尝试的第一件事就是复制该值(使用g_strdup),然后在树中使用该副本。为了防止泄漏,您可能还应该使用g_tree_new_full为您的树分配适当的销毁通知功能。