I have a class which has a few attributes like shown below, my problem is that when I remove or place the string s attribute before std::atomic<char*> atomic_input the program terminates with exception:
'std::logic_error'
what(): basic_string::_M_construct null not valid
Aborted (core dumped)
#include <string>
#include <atomic>
// In ui.cpp
class UI
{
private:
std::atomic<char*> atomic_input;
std::string s; /* this can be renamed, but removing or placing it
before the above field crashes the program */
};
// In main.cpp
#include "ui.cpp"
int main()
{
srand (time(NULL));
initscr(); /* start the curses mode */
UI* ui = new UI();
return 0;
}
The string attribute is not accessed within the program in any way, renaming it is possible. The reason why I have an atomic field is that the value is shared among several threads.
I have tried placing the string field in different lines within the class attributes, the program only crashes if the declaration is before the atomic_input.
What might be causing the problem? Is it something to do with how the classes in C++ should be defined?
Looks like I've found a solution.
std::atomic<char*> atomic_input not being initialized like seen below was causing the issue. I still don't know how the string variable was interfering with it.
My guess is that the compiler somehow interprets the string as a constructor for atomic_input. The error only occurs when atomic_input is accessed in runtime and not in the compilation.
#include <string>
#include <atomic>
// In ui.cpp
class UI
{
private:
std::atomic<char*> atomic_input{(char*)""};
// std::string s; /* Initializing the atomic char like above solved the problem */
};
Related
Shortened code I wrote for learning purposes. Still the way it is, it doesn't work properly.
Removing last line (&&) it works OK, but with it, code doesn't reach line noted as ##, expressing
segmentation error, after the "BazOnly" text displayed.
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
namespace nek{
class Baz{
int num;
std::string str;
public:
Baz(){cout<<"BazOnly"<<endl;}
string setstr(string& val){
//str.assign(val);
num= 7;
}
};
}
namespace drg{
class Deriv: nek::Baz{
public:
Deriv(char ch){cout<<"DerivChar"<<endl;}
};
};
int main(){
nek::Baz b;
string priv{"zik"};
b.setstr(priv);
cout<<"Passed here"<<endl; //##
drg::Deriv dc{'A'}; // &&
}
Compiled with g++ (option std=gnu++11), Ubuntu 16 on Virtual Box.
Question is what could be the reason for such behavior ?
string setstr(string& val){
//str.assign(val);
num= 7;
}
This method is declared as returning a std::string, but nothing actually gets returned from it. This is undefined behavior.
Most modern C++ compilers will warn you about this. If yours' did, this is an example of why you cannot ignore warning messages from your compiler, even if it did successfully compile your code.
I'm trying to use an map with string key, but it's not working and I couldn't figure out why.
I would like to have some help to understand C++ fundamentals about the usage of this so essential structure.
model.hpp
#pragma once
#include <map>
#include <utility>
#include <string>
#include <iostream>
#include "../prs/ast.h"
using namespace std;
using namespace ast;
typedef map<string, Variable> Map;
typedef pair<string, Variable> Element;
namespace model{
class Warehouse {
public:
Map stock;
Warehouse(){
Map* _stock = new Map();
stock = *_stock;
}
Variable* get(string id){
Map::iterator it = stock.find(id);
if (it != stock.end()){
return &(*it).second;
}
else {
return __define__(id);
}
}
Variable* __define__(string id){
Variable* defined = new Variable(id);
stock.insert(Element(id, *defined));
return defined;
}
};
static Warehouse* WAREHOUSE;
};
model.cpp
#pragma once
#include "model.hpp"
using namespace std;
namespace model {
Warehouse* WAREHOUSE = new Warehouse();
}
In this context, Variable is a project object defined in ast
namespace already tested, as well WAREHOUSE pointer is working accordingly, with class
initialized
The instruction stock.find(id) is throwing the mentioned error message: Segmentation fault (core dumped), what I suppose means stock isn't correct initialized.
What is exactly happening with stock initialization done at Warehouse constructor?
I understand that new keyword allocs the map and dereference its returned point would store the structure at stock Warehouse member attribute.
Am I misunderstand it?
WAREHOUSE is a static variable defined in a header. What this means is that every source file that includes that header gets its own copy of this variable, initialized to nullptr. Only one source file sets its own copy to a non-null value. Presumably, some other source file in the code not shown attempts to dereference its copy.
Make it
extern Warehouse* WAREHOUSE;
I'm trying to use the RapidXML to parse my XML file. And I did it following the example here. Instead of doing the parsing in the main function, I wrote a wrapper class called XMLParser to do the parsing job. And this really gives me a headache.
The XMLParser.hpp:
#include <iostream>
#include <string>
#include <stdio.h>
#include <vector>
#include "rapidxml/rapidxml.hpp"
using namespace std;
using namespace rapidxml;
class XMLParser {
public:
XMLParser() {};
XMLParser(const std::string &xmlString): xmlCharVector(xmlString.begin(), xmlString.end())
{
//xmlCharVector.push_back('\0');
parseXML();
}
XMLParser(const std::vector<char> &_xmlVector):xmlCharVector(_xmlVector)
{
/* xmlCharVector.push_back('\0'); */ // already done in main.cpp
if (xmlCharVector != _xmlVector) //And it turns out they're the same....
std::cout << "The two vectors are not equal" << std::endl;
else
std::cout << "They are the same" << std::endl;
parseXML();
}
private:
std::vector<char> xmlCharVector;
rapidxml::xml_document<> doc;
void parseXML();
};
The XMLParser.cpp:
#include "XMLParser.hpp"
using namespace std;
using namespace rapidxml;
void XMLParser::parseXML()
{
doc.parse<0>(&xmlCharVector[0]);
}
And here is the main.cpp:
#include <iostream>
#include <stdio.h>
#include <string>
#include <vector>
#include <fstream>
#include "XMLParser.hpp"
using namespace std;
using namespace rapidxml;
int main(int argc, char **argv)
{
xml_document<> doc;
xml_node<> *root_node;
ifstream theFile("beer.xml");
vector<char> buffer((istreambuf_iterator<char>(theFile)), istreambuf_iterator<char>());
buffer.push_back('\0');
doc.parse<0>(&buffer[0]);
root_node = doc.first_node("MyBeerJournal");
xml_node<> *engine = root_node->first_node("Brewery");
//The above code works pretty well, and I can get the element I want in XML file.
//The problem occurs when I tried to use the XMLParser
XMLParser xmlParser(buffer);
return 0;
}
The parsing process in the main function works pretty well. But when I tried to use the function in my wrapper class parseXML(), then error occured:
terminate called after throwing an instance of 'rapidxml::parse_error'
what(): expected >
Abort (core dumped)
Originally I have other code in this function, but I commented them all, and find that even with the single line doc.parse<0>(&xmlCharVector[0]);. Why it works well in main.cpp while not in the wrapper class? I really can't figure it out. Could anybody help me?
I've found out the reason... This stupid problem really takes me a long time to debug. I'm writing it here so that anyone ran into it (hope not) could save his time. The problem lies exactly in the code doc.parse<0>(&buffer[0]) in the main function. Before executing this line of code, the buffer(type of vector<char>) is like this: (by printing the vector to console)
<MyBeerJournal>
<Brewery name="Founders Brewing Company" location="Grand Rapids, MI">
<Beer name="Centennial" description="IPA" rating="A+" dateSampled="01/02/2011">
"What an excellent IPA. This is the most delicious beer I have ever tasted!"
</Beer>
</Brewery>
.....
.....
</MyBeerJournal>
It's the same with original xml file. After executing the above code, the buffer(type of vector<char>) becomes something like this:
<MyBeerJournal
<Breweryname"Founders Brewing Company location"Grand Rapids, MI>
<Beername"Centennial description"IPA rating"A+ dateSampled"01/02/2011>
"What an excellent IPA. This is the most delicious beer I have ever tasted!"
/Beer>
</Brewery>
As you can see, some angel brackets disappeared. and some other things like double quote has also been changed. So the wrapper class constructor copied the modified "xml buffer", and this not well formatted xml vector will certainly cause the second doc.parse<0>(&xmlCharVector[0]); in the wrapper class to fail. I don't know why the library writer needs to modify the char vector passed in, because the subsequent xml analysis is not relevant to the original char vector once the DOC has been created.
I'm running into an irritating problem where my program keeps crashing if I try to reference a private variable that I have created in one of my classes. I can't figure out where I am going wrong. Here is the class that calls the class that crashes:
#include <stack>
#include <fstream>
#include <ostream>
#include <cstdlib>
#include <string>
#include <set>
#include "schemeList.cpp"
using namespace std;
class dataLog
{
public:
stack<string> commands;
set<string> domain;
processor tokens;
int nextToken;
schemeList * s;
dataLog(stack<string> s, ofstream * out, processor p, int location)
{
commands = s;
tokens = p;
nextToken = location;
commands.push("<Query List>");
commands.push(":");
commands.push("Queries");
commands.push("<Rule List>");
commands.push(":");
commands.push("Rules");
commands.push("<Fact List>");
commands.push(":");
commands.push("Facts");
commands.push("<Scheme List>");
commands.push(":");
commands.push("Schemes");
checkNext();
}
void checkNext()
{
for(int i = 0; i < tokens.tags.size(); i++)
{
if(commands.top().compare(tokens.tags[i].getName())!=0)
{
if(commands.top().find("<")==0)
{
if(commands.top().compare("<Scheme List>")==0)
{
int output = (*s).process(i, tokens, domain); string hi = (*s).toString();
}
}
}
commands.pop();
}
}
};
This class creates an object of my SchemeList class, which is written out as follows:
#include "schemes.cpp"
#include <cstdlib>
#include <string>
#include <set>
using namespace std;
class schemeList
{
private:
string success;
public:
int process(int number, processor p, set<string> domain)
{
success = "HELLO";
return 13;
}
string toString()
{
return success;
}
};
As soon as I get to line 15 success = "HELLO";, the program crashes with the message
Unhandled exception at 0x00E48B66 in lab2.exe: 0xC0000005: Access violation reading
location 0xCCCCCCE4.
I am using Microsoft Visual Studio Express 2012 for Windows Desktop.
First off, the variable schemeList * dataLog::s is never initialized, so accessing it is undefined behavior, which leads to the crash. Most likely calling process on a dangling pointer and attempting to write into some memory you don't own.
Second, don't #include "schemeList.cpp". You're not supposed to include cpp files. Rather, separate declarations & implementations and include a header.
You have not initialized dataLog::s. When you call (*s).process(i, tokens, domain), you get undefined behavior.
Firstly, you're apparently including source code files in headers. This will likely break the one definition rule and go horribly wrong.
Secondly, 's' is not a very good name for a class member. It makes it almost impossible to find uses of it.
Thirdly, I can see nowhere in your code that initialises s. I can see where it gets referenced OK, but as it hasn't been initialised, the effect of dereferencing is undefined, and with luck will merely crash your program, which looks like what is happening.
Could any body offer me any reason about that?
If we do it like that, what's the outcome? Compile error?
The problem is that static initialization isnt just initialization, it is also definition. Take for example:
hacks.h :
class Foo
{
public:
static std::string bar_;
};
std::string Foo::bar_ = "Hello";
std::string GimmeFoo();
main.cpp :
#include <string>
#include <sstream>
#include <iostream>
#include "hacks.h"
using std::string;
using std::ostringstream;
using std::cout;
int main()
{
string s = GimmeFoo();
return 0;
}
foo.cpp :
#include <string>
#include <sstream>
#include <iostream>
#include "hacks.h"
using std::string;
using std::ostringstream;
using std::cout;
string GimmeFoo()
{
Foo foo;
foo;
string s = foo.bar_;
return s;
}
In this case, you can't initialize Foo::bar_ in the header because it will be allocated in every file that #includes hacks.h. So there will be 2 instances of Foo.bar_ in memory - one in main.cpp, and one in foo.cpp.
The solution is to allocate & initialize in just one place:
foo.cpp :
...
std::string Foo::bar_ = "Hello";
...
It is just a limitation in the language it self. Hopefully, when C++0x becomes reality, this limitation would go away.
I think this page gives a somehow good reason:
One of the trickiest ramifications of
using a static data member in a class
is that it must be initialized, just
once, outside the class definition, in
the source file. This is due to the
fact a header file is typically seen
multiple times by the compiler. If the
compiler encountered the
initialization of a variable multiple
times it would be very difficult to
ensure that variables were properly
initialized. Hence, exactly one
initialization of a static is allowed
in the entire program.