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/