Mongodb c++ crashing when inserting into collection inside an object - mongodb

I am using the mongocxx driver and I am trying to do a basic insert into a collection.
If I simply follow the guidelines presented here, it works fine.
However, if I put the db and collection instances inside an object, the insert crashes at runtime. So, for a simple example, I have a struct with the database and collection instances, and the try to do an insert via these instances after creating an instance of Thing in main():
#include <bsoncxx/builder/stream/document.hpp>
#include <bsoncxx/types.hpp>
#include <bsoncxx/json.hpp>
#include <mongocxx/instance.hpp>
#include <bsoncxx/json.hpp>
#include <mongocxx/client.hpp>
#include <mongocxx/stdx.hpp>
#include <mongocxx/uri.hpp>
struct Thing {
mongocxx::client client;
mongocxx::database db;
mongocxx::collection coll;
void open_connection(const char* host, const char* db_name, const char* coll_name) {
mongocxx::instance inst{};
mongocxx::uri uri(host);
client = mongocxx::client::client(uri);
db = client[db_name];
coll = db[coll_name];
}
};
int main()
{
Thing thing;
thing.open_connection("mongodb://localhost:27017", "test", "insert_test");
auto builder = bsoncxx::builder::stream::document{};
bsoncxx::document::value doc_value = builder << "i" << 1 << bsoncxx::builder::stream::finalize;
auto res = thing.coll.insert_one(doc_value.view()); //crashes
return 0;
}
I realize this can be solved by initiating the database and collection in main and storing only a pointer to the collection inside Thing.
I am however wondering about the reason for the crash, and whether it is possible to put the db an collection instances inside an object at all.

I think the problem could be that mongocxx::instance inst{}; created on stack in open_connection, so at the end of open_connection the inst is destroyed and some data may become undefined.
From documentation:
Life cycle: A unique instance of the driver MUST be kept around.
Move inst to the main function.

Related

The rule of The Big Three

Iam confused with the below question I did the program as per my understanding but it crashes what am I doing wrong? If someone can please assist me it would be much appreciated.
my main.cpp looks like this:
#include <iostream>
#include <iomanip>
#include "Number.h"
using namespace std;
int main()
{
Number n1(10);
Number n2 = n1;
n2.printNum();
n2.addOne();
n1 = n2;
n1.printNum();
return 0;
}
Then my header file looks like this:
#include <iostream>
using namespace std;
class Number
{
int *p;
public:
Number(int);
void addOne();
void printNum();
};
And the below parts for the constructor I need to complete there where it shows comments that's the part I should complete:
#include <iostream>
#include "Number.h"
using namespace std;
Number::Number(int a1)
{
*p = a1;//write the code needed to initialise the value of the member variable with a1
}
void Number::printNum()
{
cout << "The number is " << *p << endl;
}
void Number::addOne()
{
*p++;//write the code needed to increment the value of the member variable by one.
}
Then the question asks the below what should I do to the code to use the BIG THREE?
Consider the following program. Complete the class definition (where you are asked to) and check the output. You can see that that program works without error once it is completed. However, experts suggest that in any class that uses pointers and the new operator it is better to follow the rule of The Big Three. Modify the class definition to follow the rule of The Big Three and submit the new program and the output. Demonstrate the use of this pointer.
Thank you
Rohan

Mongocxx array of ObjectID in find

I'm trying to populate a query for a C++ using mongocxx driver.
The query in Javascript would be like:
{unit_id: {$in: [ObjectId('58aee90fefb6f7d46d26de72'),
ObjectId('58aee90fefb6f7d46d26de73']
}
}
I was thinking that the following code could work to generate the array part, but it doesn't compile.
#include <cstdint>
#include <iostream>
#include <vector>
#include <bsoncxx/json.hpp>
#include <bsoncxx/types.hpp>
#include <mongocxx/client.hpp>
#include <mongocxx/stdx.hpp>
#include <mongocxx/uri.hpp>
#include <mongocxx/instance.hpp>
using bsoncxx::builder::stream::close_array;
using bsoncxx::builder::stream::close_document;
using bsoncxx::builder::stream::document;
using bsoncxx::builder::stream::finalize;
using bsoncxx::builder::stream::open_array;
using bsoncxx::builder::stream::open_document;
mongocxx::instance instance {};
mongocxx::client client{mongocxx::uri{}};
mongocxx::database db = client["banff_development"];
mongocxx::collection coll = db["units"];
int main()
{
mongocxx::cursor cursor = coll.find
(document{} << "provider_id" << bsoncxx::oid("58aee90fefb6f7d46d26de4a")
<< finalize);
bsoncxx::builder::stream::document unit_filter_builder;
for (auto a: cursor)
{
unit_filter_builder << a["_id"].get_oid();
}
return 0;
}
Where can I find an working example for queries using ObjectId arrays to filter.
To build an array, you need to use the array builder, not the document builder. The declaration of the builder for the array should be bsoncxx::builder::stream::array unit_filter_builder. It also looks like you're missing a couple of includes for the various stream builder types.
As an aside, it's better to shy away from the stream builder, as it's very easy to run into issues when using it. This and this are good examples of the trickiness of using the stream builder properly. Instead of using the stream builder, you can use the basic builder, which has a much simpler implementation and gives you much saner error messages if you make a mistake.

cannot sort a vector of objects that has array in it

Hi I am using a class that has an integer and array and creating a vector of the classes objects but I cannot sort it also don't know to store in it.
I am a BEGINNER on c++ so i just wanted to know if I am wrong and how to
do that thing
here n = no of times the program has to execute
num = to store the no. of elements in vector a
but problem loop for(j=0;j<arr[i].a.end();j++)
and also pushback is not working
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class subcont
{
public:
int num;
vector<int> a;
};
int main()
{
vector<subcont> arr(100);
int i,j,k,l,n,num1,num2;
cin>>n;
for(i=0;i<n;i++)
{
cin>>arr[i].num;
for(j=0;j<arr[i].num;j++)
{
cin>>num2;
cin>>arr[i].a.pushback(num2);
}
}
for(i=0;i<n;i++)
{
sort(arr[i].a.begin(),arr[i].a.end());
}
for(i=0;i<n;i++)
{
cout<<arr[i].num;
for(j=0;j<arr[i].a.end();j++)
cout<<arr[i].a[j];
}
return 0;
}
The problems you describe sound as if you could at least compile your code, which I can't. In fact, the compiler error messages (if one first ignores the large amount of error noise generated by unhappy templates) should hint to most important problems.
Logical problems on first sight: In for(j=0;j<k;j++) the value of k is undefined. In for(j=0;j<arr[i].a.end();a++) the a++ does not make sense.
In cin>>arr[i].a.pushback[num]; the num should probably be num2. Please check your code for more such typoes.
Your sort fails because a is a C array and not a C++ container, so a.begin() and a.end() are not defined.
Stylistic problem: While it makes life a lot easier, mayn people strictly recommend to not use using namespace std;
Additional remark: Why not use std::vector<int> in place of subcont?

std::vector in MyClass ptr causing crash on destructor

I have a problem in regards to a custom class I have made. The original intention was to create a particle emitter and in this emitter are two vectors to hold colors and the particles themselves.
The problem exactly is trying to destruct this custom class which functions perfectly if you do not call the destructor, which is obviously bad.
I have reduced this to a very short, compileable example.
Test.h
#include <vector>
class Test{
public:
Test();
~Test();
protected:
std::vector<int> Ints;
};
And the main.cpp:
#include "Test.h"
int main(int argc, char **argv){
Test* t;
delete[] t;
return 0;
}
In the Implementation file is just empty constructor and destructors.
Something to note is, this only happens when the "Test" is a pointer, which would preferred to be avoided.
Will provide more information if needed. Thanks in advance.
You are deleting something that hasn't allocated a memory and that too in wrong way.
Allocate memory first
Test *t = new Test;
then,
delete t; // Note no []
Also, since C++11 is tagged, prefer using smart pointers, which do the memory management for you on its own
If t is a pointer then you need to give it something to point to first, as #P0W points out. But why not just declare t to be a local (stack) variable?
#include "Test.h"
int main(int argc, char **argv){
Test t;
return 0;
}
You are not creating object Test. You have created an pointer of type Test. For a pointer you need to use the keyword "new".
Test * t = new Test();

What is the required lifetime of objects returned by import() and exect_file()?

Below is a condensed form of this example: http://www.boost.org/doc/libs/1_51_0/libs/python/doc/v2/exec.html#examples
Python function to call from C++, stored in the file script.py:
def greet():
return 'Hello from Python!'
The C++ code to execute the Python function:
#include <iostream>
#include <string>
#include <boost/python.hpp>
using namespace boost::python;
void greet()
{
object main = import("__main__");
object global(main.attr("__dict__"));
object result = exec_file("script.py", global, global);
object greet = global["greet"];
std::string message = extract<std::string>(greet());
std::cout << message << std::endl;
}
My question is: do I need to keep the main, global and result objects alive to be able to call greet?
No, you don't. Everything that needs to be alive is kept alive by references held by the greet object, you don't need to hold objects around yourself.