Hello I'm a fresh man to c++. And today when I test a project of my code, I encountered a problem that made me feel confused.
I want to use smart pointer in my project of parse JSON, so I pass a line of string to the class: json_content, and I want the member of json_content, json_value to get the string. The compiler didn't give me any warning or error, but when I run the a.out file, it tells me that segmentation fault. I searched a lot in Google, however I didn't find any solutions to this problem. Could any one help me? Thanks a lot! :)
BTW, my OS is MacOSX x86_64-apple-darwin18.2.0, compiler is Apple LLVM version 10.0.0 (clang-1000.10.44.4)
Here is the code:
#include <string>
#include <iostream>
#include <memory>
#include <typeinfo>
using namespace std;
class json_content {
public:
string json_value;
};
int main()
{
shared_ptr<json_content> c;
shared_ptr<string> p2(new string("this is good"));
// segmentation fault
c->json_value = *p2;
// this is also bad line!
c->json_value = "not good, too!";
return 0;
}
By default, a shared_ptr is nullptr (see API). You can't de-reference a nullptr. You need to initialize c first:
#include <string>
#include <iostream>
#include <memory>
#include <typeinfo>
using namespace std;
class JsonContent {
public:
string json_value;
};
int main() {
shared_ptr<JsonContent> c = std::make_shared<JsonContent>();
shared_ptr<string> p2 = std::make_shared<string>("This is good.");
c->json_value = *p2;
c->json_value = "This is also good!";
cout << c->json_value << endl;
return 0;
}
Demo: http://cpp.sh/5fps7n.
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 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.
This is really driving me crazy:
#include <iostream>
#include <vector>
#include <string.h>
#include <thread>
using namespace std;
void test() {
vector<string> myvector;
string a("Teststring");
myvector.push_back(a);
cout << myvector.begin()->length() << endl;
}
int main() {
thread(test).join();
return 0;
}
The code compiles fine with the -std=c++11 flag to the compiler and the -pthread flag to the linker.
BUT: Eclipse does either know the std::thread or the myvector.begin()->length(), even if the code runs fine eclipse warns me "Method 'length' could not be resolved".
I tried every possible solution in here: Eclipse CDT C++11/C++0x support without any success. This took me so many hours now, what am I doing wrong?!
Is there anybody getting a project setup without problems with this code?
EDIT: Other code example - same problem:
#include <iostream>
#include <vector>
#include <thread>
using namespace std;
class TestClass {
public:
void test() {
cout << "test" << endl;
}
};
void test() {
vector<TestClass> testClassVector;
TestClass x;
testClassVector.push_back(x);
testClassVector.begin()->test();
}
int main() {
thread(test).join();
return 0;
}
Compiles and runs correct, but returns in eclipse: Method 'test' could not be resolved
EDIT:
working versions:
((TestClass)*(testClassVector.begin())).test();
TestClass foo2 = *(testClassVector.begin());
foo2.test();
still not working:
testClassVector.begin()->test();
The last compiles and works like the two above, but eclipse still claims:
Method 'test' could not be resolved
Maybe I'm wrong, but I think your problem don't come from Eclypse. Juste, begin() on a vector return a std::vector<T>::iterator first, this is not a pointer and there is no method length, but you can ask for the vector size with myvector.size(); if this is what you want.
The problem could come from your #include <string.h> that is not the same as #include <string>, string.h is for string operation like strcmp, strstr, etc... juste string will define the std::string object.
I don't have Eclipse set up but the problem appears to be around std::string. Does the problem go away if you remove the threading from the example? (I also changed to #include <string> instead of string.h)
#include <iostream>
#include <vector>
#include <string>
#include <thread>
using namespace std;
#if 0
void test() {
vector<string> myvector;
string a("Teststring");
myvector.push_back(a);
cout << myvector.begin()->length() << endl;
}
#endif
int main() {
//thread(test).join();
vector<string> myvector;
string a("Teststring");
myvector.push_back(a);
cout << myvector.begin()->length() << endl;
return 0;
}
That should hopefully print out 10.
Update from comment:
Does this generate the Eclipse warning?
auto tmp = *(myvector.begin());
std::cout << tmp.length() << std::endl;
What about this?
std::string foo("abc123");
std::cout << foo.length() << std::endl;
I guess one more too:
std::string foo2 = *(myvector.begin());
std::cout << foo2.length() << std::endl;
The solution found:
I downloaded eclipse kepler Kepler
Created a new project and tried to compile this source code (like above):
#include <iostream>
#include <vector>
#include <thread>
using namespace std;
class TestClass {
public:
void test() {
cout << "test" << endl;
}
};
void test() {
vector<TestClass> testClassVector;
TestClass x;
testClassVector.push_back(x);
testClassVector.begin()->test();
}
int main() {
thread(test).join();
return 0;
}
On the first run eclipse told me, thread belongs to the new c++11 standard and I have to add -std=c++11 to the compiler flags. To use thread I also added -pthread to the linker flags. With this steps the code could be compiled, but eclipse marks the thread still as unknown. To fix this I proceeded the following step:
Under C/C++ Build (at project settings), find the Preprocessor Include Path and go to the Providers Tab. Deselect all except CDT GCC Builtin Compiler Settings. Then untag Share settings entries … . Add the option -std=c++11 to the text box called Command to get compiler specs.
Found here.
Now - unbelievable but true - it works, even without any errors marked by eclipse. The solution is using the (beta) version of eclipse, wich seems to handle this in a better way.
Thanks for all your help!
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.
I'm having problem with stringstream.my visual studio nor linux g++ can understand stingstream. I've added sstream but it does'nt solve anything. I've worked with it before and really don't know what's up with it now?
#include <sstream>
#include <stdlib.h>
#include "SymbolTable.cpp"
#include "setjmp.h"
using namespace std;
jmp_buf *bfj;
int TOP , SP=3 ;
struct types{int int_val;float float_val;char char_val;bool bool_val;};
types DS[6400];
int main(){
...//some code here
label38 : stringstream s;
label39 : bfj = (jmp_buf *)"label65";
label40 : longjmp(*bfj,1);;
label41 : goto label43;
label42 : TOP=SP;
//some code here
}
I'm writing a compiler so the code is the output,that's why it may seams a bit odd.
If you include #include <sstream> then you must also reference the class by:
std::stringstream or declare using namespace std; before using it.
If you post more information we could provide more detailed help.
This code compiles fine for me under G++:
#include <sstream>
#include <stdlib.h>
#include "setjmp.h"
using namespace std;
jmp_buf *bfj;
int TOP , SP=3 ;
struct types{int int_val;float float_val;char char_val;bool bool_val;};
types DS[6400];
int main(){
label38 : stringstream s;
label39 : bfj = (jmp_buf *)"label65";
label40 : longjmp(*bfj,1);;
label41 : goto label43;
label42 : TOP=SP;
label43 : (void)0;
//some code here
}
The only difference is that I removed #include "SymbolTable.cpp", and added a label43.
So apparently, if it doesn't work for you, the problem is in some of the code you omitted. The //some code here parts or in SymbolTable.cpp
Of course, it also seems very suspicious that you're including a cpp file. That is most likely an error.