当使用C ++客户端库并保留从cursor-> next()返回的BSONObj对象时,后续的新查询(使用相同的连接)会以某种方式破坏该对象吗?我的理解是它是一个智能指针,并将一直存活,直到最后一次引用超出范围。然而,实践告诉我,后续查询似乎会破坏对象。在遍历新查询后访问对象的hasField / getField方法时出现分段错误。
以下是相关代码:
BSONObj DB::getmsg
(
const string &oid
)
{
BSONObj query = BSON("_id" << OID(oid));
auto_ptr<DBClientCursor> cursor = c.query("nsdb.messages", query);
if (cursor->more())
return cursor->next();
throw Exception("could not find object %s", oid.c_str());
}
void DB::getchildren
(
const string &oid,
vector<BSONObj> &children
)
{
BSONObj query = BSON("parent" << oid);
BSONObj fields = BSON("_id" << 1);
auto_ptr<DBClientCursor> cursor =
c.query("nsdb.messages", query, 0, 0, &fields);
while (cursor->more())
children.push_back(cursor->next());
}
void DB::message
(
const string &oid,
string &str,
bool body
)
{
connect();
BSONObjBuilder response;
try
{
BSONObj n = getmsg(oid);
response.append("message", n);
vector<BSONObj> children;
getchildren(oid, children);
if (children.size() > 0)
{
BSONArrayBuilder a;
vector<BSONObj>::iterator i;
for (i = children.begin(); i != children.end(); i++)
{
if (!(*i).isEmpty() && (*i).hasField("_id"))
{
string child = (*i).getField("_id").__oid().str();
a.append("http://127.0.0.1:12356/lts/message/" + child);
}
}
if (a.len() > 0)
response.append("children", a.done());
}
if (body)
{
string fname;
if (n.hasField("fname"))
fname = n.getField("fname").str();
if (fname.empty())
{
throw Exception("no fname field in message record %s",
n.jsonString().c_str());
}
auto_mmapR<const void *, int> m(fname);
response.appendBinData("body", m.size(), BinDataGeneral,
m.get());
}
str = response.obj().jsonString();
}
catch (const DBException &x)
{
throw Exception("%s", x.what());
}
}
如果我移动部件:
string fname;
if (n.hasField("fname"))
fname = n.getField("fname").str();
在调用getchildren(...)之前的某个位置,然后从消息中正确检索fname字段,否则抛出异常'消息记录中没有fname字段'
答案 0 :(得分:1)
好的,我没有太多了解你的代码,但简短的回答: - 游标返回的数据在下一次迭代或光标被销毁时无效。 使用“ getOwned()”获得BSONObj对象的副本:
cursor->next().getOwned();