http://www.easysoft.com/developer/languages/c/odbc_tutorial.html

我按照上面的教程使用ODBC查询MSSQL数据库。我工作了
现在,我试图将其包装在C ++类中。我看到一些意外的行为
在下面的代码块中。

while (SQL_SUCCEEDED(ret = SQLFetch(stmt)))
{
  vector<string> vRow;
  // loop through columns
  for (SQLUSMALLINT i = 1; i<= numCols; i++)
  {
    SQLINTEGER indicator;
    char buf[500];

    SQLRETURN data_ret;
    data_ret = SQLGetData(stmt, i, SQL_C_CHAR, buf, sizeof(buf),
                          (SQLLEN*) &indicator); // <--- this call makes the first
                                                 // <--- entry of vRow disappear

    if (SQL_SUCCEEDED(data_ret))
    {
      if (indicator == SQL_NULL_DATA)
      {
        strcpy(buf, "NULL");
      }

      vRow.push_back(string(buf)); // <--- This line seg faults
    }
  }
}


第一次通过for循环,一切都很好,但是在第二次通过时,我遇到了分段错误
    vRow.push_back(string(buf));

逐步使用gdb可以看到,该问题实际上是由第二次调用SQLGetData引起的。执行该行之后,我无法访问vRow的第一个元素。

(gdb) p vRow
$1 = std::vector of length 813681, capacity 813681 = {Cannot access memory at address 0x0


对我来说,这似乎是vRows中的第一个条目是buf的浅表副本,对SQLGetData的调用破坏了内存位置,但是我阅读的所有内容似乎都表明字符串在进行深层复制。

我尝试过在将buf的深层副本推入vRow之前将其“强制”插入字符串中,但是所有努力都表现出了这种行为。

我正在使用带有这些标志的g ++进行编译-std = c ++ 0x -lboost_regex -lodbc

有人可以帮我弄清楚这里发生了什么吗?
先感谢您。

更新
将指标变量从类型SQLINTEGER更改为SQLLEN可解决此问题。

在sqltypes.h中,标头SQLLEN是长整数,而SQLINTEGER是整数。因此,对SQLGetData的调用实质上将long转换为int。

最佳答案

将指标变量从类型SQLINTEGER更改为SQLLEN可解决此问题。

在sqltypes.h中,标头SQLLEN是长整数,而SQLINTEGER是整数。因此,对SQLGetData的调用实质上将long转换为int。

感谢大家的帮助。

关于c++ - 调用SQLGetData后C++ vector.push_back(string)seg错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17215138/

10-10 22:29