runtime error with mongocxx::options::find - mongodb

It works fine when I do query without option
document condition;
condition << "age" << 22;
auto cursor = collection_.find(condition.view());
for (auto&& doc : cursor)
{
std::cout << bsoncxx::to_json(doc) << std::endl;
}
but once I use mongocxx::options::find opts
document condition;
condition << "age" << 22;
mongocxx::options::find opts{};
opts.limit(1);
auto cursor = collection_.find(condition.view(), opts);
for (auto&& doc : cursor)
{
std::cout << bsoncxx::to_json(doc) << std::endl;
}
read access permission conflicts error occured
enter image description here

I recompiled mongocxx and built a new project, the error didn't appear. Maybe there is something wrong with my previous environment.

Related

Questions about select()

Considering the following class method:
void TCPServer::listenWithTimeout() {
fd_set descrSet;
struct timeval timeout = {1, 0};
while (listeningThread.active) {
std::cout << "TCP Server thread is listening..." << std::endl;
FD_ZERO(&descrSet);
FD_SET(mySocketFD, &descrSet);
int descrAmount = select(mySocketFD + 1, &descrSet, NULL, NULL, &timeout);
if (descrAmount > 0) {
assert(FD_ISSET(mySocketFD, &descrSet));
int threadIndx = findAvailableThread();
if (threadIndx < 0) {
std::cout << "Connection not accepted: no threads available..." << std::endl;
} else {
joinThread(threadIndx);
int newSocketFD = accept(mySocketFD, (struct sockaddr *) &mySocket, &clieAddrssLen);
std::cout << "TCP Client connected..." << std::endl;
connectionThreads[threadIndx].thread = std::thread(TCPServer::startTCPConnectionWithException, std::ref(*this), threadIndx, newSocketFD);
connectionThreads[threadIndx].active = true;
}
}
}
std::cout << "TCP Server thread is terminating..." << std::endl;
}
Here are some question:
when there are not available threads (findAvailableThreads() returns -1), is it a normal behaviour that select() doesn't wait its timeout and so the while loop iterates really fast until a new thread is available?
if yes, how could I avoid these really fast iterations? Instead of using something like a simple sleep() at line 13 inside the if branch, is there a way to let select() restore its timeout? Or even, is there a way to completely reject the incoming connection pending?
when there are not available threads (findAvailableThreads() returns -1), is it a normal behaviour that select() doesn't wait its timeout and so the while loop iterates really fast until a new thread is available?
Yes, because under that condition, you are not calling accept(), so you are not changing the listening socket's state. It will remain in a readable state as long as it has a client connection waiting to be accept()'ed.
if yes, how could I avoid these really fast iterations?
Call accept() before checking for an available thread. If no thread is available, close the accepted connection.
Instead of using something like a simple sleep() at line 13, inside the if branch, is there a way to let select() restore its timeout?
The only way is to accept() the connection that put the listening socket into a readable state, so it has a chance to go back to a non-readable state. The timeout will not apply again until the socket is no longer in a readable state.
Or even, is there a way to completely reject the incoming connection pending?
The only way is to accept() it first, then you can close() it if needed.
Try this:
void TCPServer::listenWithTimeout() {
fd_set descrSet;
while (listeningThread.active) {
std::cout << "TCP Server thread is listening..." << std::endl;
FD_ZERO(&descrSet);
FD_SET(mySocketFD, &descrSet);
struct timeval timeout = {1, 0};
int descrAmount = select(mySocketFD + 1, &descrSet, NULL, NULL, &timeout);
if (descrAmount > 0) {
assert(FD_ISSET(mySocketFD, &descrSet));
int newSocketFD = accept(mySocketFD, (struct sockaddr *) &mySocket, &clieAddrssLen);
if (newSocketFD != -1) {
int threadIndx = findAvailableThread();
if (threadIndx < 0) {
close(newSocketFD);
std::cout << "Connection not accepted: no threads available..." << std::endl;
} else {
joinThread(threadIndx);
std::cout << "TCP Client connected..." << std::endl;
connectionThreads[threadIndx].thread = std::thread(TCPServer::startTCPConnectionWithException, std::ref(*this), threadIndx, newSocketFD);
connectionThreads[threadIndx].active = true;
}
}
}
}
std::cout << "TCP Server thread is terminating..." << std::endl;
}

Why is the code failing in the Destructor?

I have gone through stackoverflow questions similar to "Why is the destructor called twice?". My question can be a similar one but with a small change. I am getting an error when running the following code:
struct Employee{
char *name;
char *tag;
Employee *employee;
Employee(){
name = NULL;
tag = NULL;
employee = NULL;
}
//copy constructor
Employee(const Employee &obj){
cout << "Copy constructor called" << endl;
name = (char*)malloc(sizeof(char)*strlen(obj.name));
strcpy(name, obj.name);
tag = (char*)malloc(sizeof(char)*strlen(obj.tag));
strcpy(tag, obj.tag);
employee = (struct Employee*)malloc(sizeof(obj.employee));
employee = obj.employee;
}
//overloaded assignment operator
void operator = (const Employee &obj){
cout << "Assignment operator called" << endl;
if (this == &obj){
return;
}
strcpy(name, obj.name);
strcpy(tag, obj.tag);
employee = obj.employee;
}
//destructor
~Employee(){
cout << "Destructor called" << endl;
if (name != NULL){
cout << "Freeing name" << endl;
free(name);
name = NULL;
}
if (tag != NULL){
cout << "Freeing tag" << endl;
free(tag);
tag = NULL;
}
if (employee != NULL){
cout << "Freeing employee" << endl;
free(employee);
employee = NULL;
}
}
};
Employee createNode(){
Employee emp;
emp.name = (char*)malloc(sizeof(char)* 25);
strcpy(emp.name, "Alan");
emp.tag = (char*)malloc(sizeof(char)* 25);
strcpy(emp.tag, "Engineer");
emp.employee = (struct Employee*)malloc(sizeof(struct Employee));//just created memory, no initialization
return emp;
}
Employee get(){
//Employee emp = createNode();
//return emp;
return createNode();
}
int main(){
Employee emp = get();
getchar();
return 0;
}
I debugged the code and found that error is raising when the destructor is called second time when the main function exits.
1) I want to know why the code fails to run?
2) Are there any memory leaks?
3) How can I fix the error properly deallocating memory?
Thanks in advance.
Update:
As per the three Rule I have also added a copy constructor and overloaded the assignment operator. But the error(Expression : _crtisvalidheappointer(puserdata)) is raising. After checking in the Google I could see that some where the Heap corruption is happening. When I comment the initialization of the Struct member employee in the createNode() then I could see the error raising when trying to free the employee in destructor. So I suspect the problem is with the employee struct member. Please help me with this.I am using Visual studio for debugging and running.
Your problem is a lack of copy construct and assignment operator in your class. As a result you are freeing the strings within the class multiple times.
Just tried your code and found out a few issues that causes a crash:
1) strlen returns length of string without null terminator character, but strcpy requires that additional byte, so your allocating should look like that:
name = (char*)malloc(strlen(obj.name)+1);
2) When you copy employee, you copy pointer, so you have memory leak and employee pointer as a dangling one.
Also malloc cannot work with constructors, therefore after
employee = (struct Employee*)malloc(sizeof(obj.employee));
employee has a garbage inside.

How to retrieve the value of a specific field using mongo cxx driver

Say, I inserted the following document using the mongo command line or shell:
db.Users.insert(
{
"user info":{
"user name" : "Joe",
"password" : "!##%$%" ,
"Facebook" : "aaa",
"Google" : "joe z"
}
}
)
Then this entry is logged into the database with a system created ID.
If I want to achieve the following command line which only returns the value of a specific filed (_id in this case), using the cxx driver how should I do it?
Here is the command line:
db.Users.find({"user info.user name": "Joe"}, {"_id":1})
I tried the following C++ code
bsoncxx::builder::stream::document document{} ;
document<<"user info.user name"<<"Joe"<<"_id"<<1;
auto cursor = myCollection.find(document.view());
for (auto && doc : cursor) {
std::cout << bsoncxx::to_json(doc) << std::endl;
}
It simply give me nothing.
If I set
document<<"user info.user name"<<"Joe"
Then it returns the entire JSON message for me.
Please let me know if you have any better ideas.
Here's an example:
#include <iostream>
#include <bsoncxx/builder/stream/document.hpp>
#include <bsoncxx/json.hpp>
#include <mongocxx/client.hpp>
#include <mongocxx/options/find.hpp>
#include <mongocxx/instance.hpp>
#include <mongocxx/uri.hpp>
using bsoncxx::builder::stream::document;
using bsoncxx::builder::stream::open_document;
using bsoncxx::builder::stream::close_document;
using bsoncxx::builder::stream::finalize;
int main(int, char **) {
mongocxx::instance inst{};
mongocxx::client conn{mongocxx::uri{}};
auto coll = conn["test"]["foo"];
coll.drop();
// Insert a test document
auto joe = document{} << "user info" << open_document << "user name"
<< "Joe" << close_document << finalize;
auto result = coll.insert_one(joe.view());
std::cout << "Inserted " << result->inserted_id().get_oid().value.to_string()
<< std::endl;
// Create the query filter
auto filter = document{} << "user info.user name"
<< "Joe" << finalize;
// Create the find options with the projection
mongocxx::options::find opts{};
opts.projection(document{} << "_id" << 1 << finalize);
// Execute find with options
auto cursor = coll.find(filter.view(), opts);
for (auto &&doc : cursor) {
std::cout << bsoncxx::to_json(doc) << std::endl;
}
}

unordered_map::find() and two iterators

Having a class with a private member
std::unordered_map<std::string, size_t> myMap;
and the corresponding getter
std::unordered_map<std::string, size_t> getMyMap() const {return myMap;}
I observe strange behaviour by applying std::unordered_map::find() two times, each time saving the returned iterator, e.g.
auto pos1 = test.getMyMap().find("a");
auto pos2 = test.getMyMap().find("a");
Altough I look for the same key "a" the iterator points to different elements. The following sample code illustrates the problem:
#include <iostream>
#include <unordered_map>
#include <vector>
#include <string>
class MyMap{
public:
MyMap(){
myMap= {
{"a", 1},
{"b", 2}
};
}
std::unordered_map<std::string, size_t> getMyMap() const {return myMap;}
private:
std::unordered_map<std::string, size_t> myMap;
};
int main(){
MyMap test;
auto pos1 = test.getMyMap().find("a");
auto pos2 = test.getMyMap().find("a");
std::cout << pos1->first << "\t" << pos1->second << std::endl;
std::cout << pos2->first << "\t" << pos2->second << std::endl;
}
Compiling with g++ -std=c++11 and running gives
b 2
a 1
where the first line is unexpected. It should be "a 1".
Changing the code to
auto pos3 = test.getMyMap().find("a");
std::cout << pos3->first << "\t" << pos3->second << std::endl;
auto pos4 = test.getMyMap().find("a");
std::cout << pos4->first << "\t" << pos4->second << std::endl;
results in the correct output
a 1
a 1
Furthermore just creating an unordered_map in the main file and applying find() works. It seems the problem is connected to the getter-method, maybe to return-value-optimisation. Do you have any explanations for this phenomena?
It's because you have undefined behavior in your code. The getMyMap returns a copy of the map, a copy that is destructed once the expression test.getMyMap().find("a") is done.
This means you have two iterators that are pointing to no longer existing maps.
The solution is very simple: Make getMyMap return a constant reference instead:
std::unordered_map<std::string, size_t> const& getMyMap() const;
That it seems to work in the latter case, is because that's a pitfall of undefined behavior, it might sometime seem like it works, when in reality it doesn't.
test.getMyMap().find("a"); does find on a copy of original myMap which is destructed after the expression is complete, making the iterators pos1 and pos2 to non-existing map, invoking an undefined behaviour
Instead you can play around like following :
auto mymap = test.getMyMap() ; // Store a copy
auto pos1 = mymap.find("a"); // Then do stuff on copy
auto pos2 = mymap.find("a");

Flex and Lemon Parser

I'm trying to learn flex and lemon, in order to parse a (moderately) complex file format. So far, I have my grammar and lex file and I believe it is correctly parsing an example file. Right now, I want to pass the token text scanned with flex to lemon.
The flex YYSTYPE is defined as
#define YYSTYPE char*
The lemon token type is
%token_type {char *}
However, if I have a set of rules in lemon:
start ::= MATDEF IDENTIFIER(matName) LEFT_CURLY_BRACE(left) materialDefinitionBody(mBody) RIGHT_CURLY_BRACE(right) .
{
std::string r = std::string(matName) + std::string(left) + mBody + std::string(right);
std::cout << "result " << r << std::endl;
}
materialDefinitionBody(r) ::= techniqueList .
{
r = "a";
}
the output will be
result a
when it should be something like
mat1 { a }
My main parsing loop is:
void parse(const string& commandLine) {
// Set up the scanner
yyscan_t scanner;
yylex_init(&scanner);
YY_BUFFER_STATE bufferState = yy_scan_string(commandLine.c_str(), scanner);
// Set up the parser
void* shellParser = ParseAlloc(malloc);
yylval = new char[512];
int lexCode;
do {
yylval[0] = 0;
lexCode = yylex(scanner);
cout << lexCode << " : " << yylval << std::endl;
Parse(shellParser, lexCode, yylval);
}
while (lexCode > 0);
if (-1 == lexCode) {
cerr << "The scanner encountered an error.\n";
}
// Cleanup the scanner and parser
yy_delete_buffer(bufferState, scanner);
yylex_destroy(scanner);
ParseFree(shellParser, free);
}
The cout line is printing the correct lexCode/yylval combination.
What is the best way? I can't find anything that works.
You need to have
yylval = new char[512];
inside the do-while loop.