I have a class that has a bsoncxx::document::view view
as a private
attribute, and a method that get a document from the Mongo database and save the result in the local bsoncxx::document::value value
variable and then get the view from the value.view()
and save it in the class bsoncxx::document::view view
variable:
const bool User::search_one_by_id(const std::string &id = "")
{
// The prototype of the method below: const std::tuple<bool, bsoncxx::document::value> search_one_by_id(mongocxx::collection &, const std::string &) const;
auto status = Crud::search_one_by_id(this->collection, id);
if (std::get<0>(status))
{
// Error
return EXIT_FAILURE;
}
else
{
// Success
bsoncxx::document::value value = std::get<1>(status);
bsoncxx::document::view view = value.view();
this->view = view;
return EXIT_SUCCESS;
}
}
The problem is that if I get some element from the view in the method above, i.e the code below before the return EXIT_SUCCESS
, no errors are issued.
bsoncxx::document::element element = this->view["first_name"];
std::cout << "First Name: " << element.get_utf8().value.to_string();
But if I get a view, save it in the bsoncxx::document::view view
variable and try to get some element from the view in another class method:
void get_element()
{
bsoncxx::document::element element = this->view["first_name"];
std::cout << "First Name: " << element.get_utf8().value.to_string();
}
I receive the error:
terminate called after throwing an instance of 'bsoncxx::v_noabi::exception'
what(): unset document::element
Makefile:26: recipe for target 'run' failed
make: *** [run] Aborted (core dumped)
I had tried to use a pointer to save the reference to the view that I get in the search_one_by_id
method. I had check if the type of the attribute (first_name
) I'm getting is the right type to get the value of the element. I had check if the attribute exist in the document. I had tried to use the release()
method from the view
in the User::search_one_by_id
. I had check if the view is empty through:
if (this->view.empty())
{
std::cout << "Empty: " << this->view.empty();
}
else
{
std::cout << "Loaded: " << this->view.empty() << " length " << this->view.length();
}
Inside the get_element
method, and the output is:
# If I comment the call to search_one_by_id
$ Empty: 1
# If I enable the call to search_one_by_id
$ Loaded: 0 length 129
The GDB log to backtrace
:
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1 0x00007ffff6fd7801 in __GI_abort () at abort.c:79
#2 0x00007ffff762c957 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007ffff7632ab6 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4 0x00007ffff7632af1 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5 0x00007ffff7632d24 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6 0x00007ffff793985c in bsoncxx::v_noabi::document::element::type() const () from /usr/local/lib/libbsoncxx.so._noabi
#7 0x00007ffff7939abc in bsoncxx::v_noabi::document::element::get_utf8() const () from /usr/local/lib/libbsoncxx.so._noabi
#8 0x0000555555559353 in User::get_element() ()
#9 0x0000555555556668 in main ()
Some tips ? The project can be found on Github
References:
Unset Document::element, MongoCXX Find Option Projection
document::element::operator[] overloads should not throw when given an invalid element
i think you need to keep the pointer to buffer of value somewhere. view object is pointing to deleted memory i suppose. try something like this
class User
{
bsoncxx::document::value _value; <<< store at class level
};
const bool User::search_one_by_id(const std::string &id = "")
{
// The prototype of the method below: const std::tuple<bool, bsoncxx::document::value> search_one_by_id(mongocxx::collection &, const std::string &) const;
auto status = Crud::search_one_by_id(this->collection, id);
if (std::get<0>(status))
{
// Error
return EXIT_FAILURE;
}
else
{
// Success
_value = std::get<1>(status);
this->view = _value.view();
return EXIT_SUCCESS;
}
}