我正在爲一個類進行編程分配,並且正在得到一個非常奇怪的問題。技術問題是,當我嘗試對某個特定向量執行任何操作時,我遇到了seg錯誤,但是它所在的對象以及對象所在的對象的行爲真的很奇怪。我懷疑這可能是一個簡單的語法錯誤,我不知道如何最好地解決,所以讓我們從這個開始。如果這個語法無效或者只是半有效的,你可能不需要讀取其餘的(除非改變它不起作用)。C++類未正確初始化
總之,這裏的我很擔心(我Database.h文件addRel
功能)代碼:
#ifndef DATABASE_H_
#define DATABASE_H_
#include "Parser.h"
#include "Relation.h"
#include <map>
class Database {
private:
std::map<std::string, Relation> relations;
std::stringstream out;
public:
Database() {}
~Database() {}
Relation* addRel(std::string RelName) {
Relation* tmp = getRel(RelName);
if(tmp == NULL) {
relations.insert(std::pair<std::string, Relation> (RelName, Relation(RelName))); //Is this a valid approach?
tmp = getRel(RelName);
}
return tmp;
}
bool findRel(std::string RelName) {return getRel(RelName) != NULL;}
Relation* getRel(std::string RelName) {return &relations.find(RelName)->second;}
...
};
我完全不希望創建該功能的Relation
對象,但我需要有一個Relation
對象傳入relations.insert
,所以我只是在函數參數中調用Relation的構造函數。如果有更好的方法來做到這一點,這可能是我的悲傷的原因,否則我擔心最壞的打算,所以這裏的一串代碼和終端輸出:
Tuple.h(沒有的.cpp):
#ifndef TUPLE_H_
#define TUPLE_H_
#include <string>
#include <vector>
class Tuple : public std::vector<std::string> {};
//This approach was specifically encouraged by my instructor
#endif
Scheme.h(沒有的.cpp):
#ifndef SCHEME_H_
#define SCHEME_H_
#include "Tuple.h"
#include <utility>
class Scheme {
private:
std::vector<std::string> attrs;
std::string test; //for testing purposes
public:
Scheme() {
attrs.clear();
test = "This is a scheme.";
}
~Scheme() {}
void addAttr(std::string newAttr) {attrs.push_back(newAttr);}
std::vector<std::string>* getAttrs() {return &attrs;}
void clear() {attrs.clear();}
std::string getTest() {return test;}
};
#endif
Relation.h(的.cpp無關):
#ifndef RELATION_H_
#define RELATION_H_
#include "Scheme.h"
#include "Tuple.h"
#include <set>
class Relation {
private:
std::string name;
Scheme idents;
...
public:
Relation(std::string newName) : name(newName) {}
~Relation() {}
std::string getName() {return name;}
Scheme* getScheme() {return &idents;}
...
};
#endif
Database.h(ē的.cpp下面xcerpt):
#ifndef DATABASE_H_
#define DATABASE_H_
#include "Parser.h"
#include "Relation.h"
#include <map>
class Database {
private:
std::map<std::string, Relation> relations;
std::stringstream out;
public:
Database() {}
~Database() {}
Relation* addRel(std::string RelName) {
Relation* tmp = getRel(RelName);
if(tmp == NULL) {
relations.insert(std::pair<std::string, Relation> (RelName, Relation(RelName))); //Is this a valid approach?
tmp = getRel(RelName);
}
return tmp;
}
bool findRel(std::string RelName) {return getRel(RelName) != NULL;}
Relation* getRel(std::string RelName) {return &relations.find(RelName)->second;}
...
};
#endif
Database.cpp(最有趣的文件):
#include "Database.h"
#include <iostream>
using namespace std;
void Database::evalSchemes(vector<Predicate> schemes) {
out << "Scheme Evaluation\n\n";
for(unsigned int i = 0; i < schemes.size(); i++) {
string name = schemes[i].getName();
Relation* trel = addRel(name);
Scheme* tsch = trel->getScheme();
cout << "\nEvaluating scheme " << name << "\ni = " << i
<< "\ntrel is " << trel->getName() << "\ntsch = " << tsch
<< "\nTest = " << tsch->getTest() << "\n";
tsch->clear(); //Segfaults here if this line is present
std::vector<Parameter> tvec = schemes[i].getVector();
for(unsigned int j = 0; j < tvec.size(); j++) {
vector<string>* tattrs = tsch->getAttrs();
string new_attr = tvec[j].getValue();
cout << "\n\tAdding attribute " << new_attr << "\n\tj = " << j
<< "\n\tVector size = " << tattrs->size() << "\n";
tsch->addAttr(new_attr); //Segfaults here otherwise
}
}
}
...
Main.cpp的:
#include "Scanner.h"
#include "Parser.h"
#include "Database.h"
#include <iostream>
using namespace std;
int main(int argc, char* argv[]) {
if(argc < 3) {
cout << "\nIncorrect program usage.\nPlease provide input and output file names.\n";
return 0;
}
else {
Scanner mainScanner(argv[1]);
Parser mainParser;
Database mainDatabase;
mainScanner.scanAll();
mainParser.importVector(mainScanner.getVector());
mainParser.parseAll();
DatalogProgram mainProg = mainParser.getProgram();
//Everything up to this point works just fine
mainDatabase.evalSchemes(mainProg.getSchemes()); //Segfaults during this function
mainDatabase.evalFacts(mainProg.getFacts());
mainDatabase.evalQueries(mainProg.getQueries());
mainDatabase.output(argv[2]);
return 0;
}
}
下面是從程序的輸出。我在Ubuntu 14.04和ZSH的gdb中運行,使用g ++編譯,包括回溯的輸出。第二個有更多的信息,所以我評論了該計劃的結果。
如果我試圖修改它之前清除載體:
(gdb) run in30.txt act30.txt
Starting program: /home/stephen/Dropbox/Code/CS_236/Lab3-Database/v1.0.1 in30.txt act30.txt
Evaluating scheme SK
i = 0
trel is @���� ����X����������� �����������������������������������
tsch = 0x7fffffffd878
Test = S
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7b90350 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()()
from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
(gdb) bt
#0 0x00007ffff7b90350 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()()
from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#1 0x000000000040ac7a in std::_Destroy<std::string> (__pointer=0x0) at /usr/include/c++/4.8/bits/stl_construct.h:93
#2 0x0000000000409838 in std::_Destroy_aux<false>::__destroy<std::string*> (__first=0x0,
__last=0x7ffff7dc04e0 <vtable for std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >+64>)
at /usr/include/c++/4.8/bits/stl_construct.h:103
#3 0x00000000004070aa in std::_Destroy<std::string*> (__first=0x0,
__last=0x7ffff7dc04e0 <vtable for std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >+64>)
at /usr/include/c++/4.8/bits/stl_construct.h:126
#4 0x00000000004056c3 in std::_Destroy<std::string*, std::string> (__first=0x0,
__last=0x7ffff7dc04e0 <vtable for std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >+64>)
at /usr/include/c++/4.8/bits/stl_construct.h:151
#5 0x0000000000405ab8 in std::vector<std::string, std::allocator<std::string> >::_M_erase_at_end (this=0x7fffffffd878, __pos=0x0)
at /usr/include/c++/4.8/bits/stl_vector.h:1352
#6 0x0000000000404688 in std::vector<std::string, std::allocator<std::string> >::clear (this=0x7fffffffd878)
at /usr/include/c++/4.8/bits/stl_vector.h:1126
#7 0x00000000004038c8 in Scheme::clear (this=0x7fffffffd878) at Scheme.h:19
#8 0x0000000000401f81 in Database::evalSchemes (this=0x7fffffffd840, schemes=std::vector of length 1, capacity 1 = {...})
at Database.cpp:15
#9 0x000000000040c57f in main (argc=3, argv=0x7fffffffe238) at Main.cpp:26
(gdb)
而這裏的,如果我評論該行發生了什麼:
(gdb) run in30.txt act30.txt
Starting program: /home/stephen/Dropbox/Code/CS_236/Lab3-Database/v1.0.1 in30.txt act30.txt
Evaluating scheme SK //this is normal
i = 0 //this is normal
trel is @���� ����X����������� ����������������������������������� //should be the relation's name
tsch = 0x7fffffffd878 //memory address, just to make sure it isn't NULL
Test = S //should be "This is a scheme."
Adding attribute A //this is normal
j = 0 //this is normal
Vector size = 17592168972444 /should be 0; I haven't done anything with this vector yet
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7b9146f in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&)()
from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
(gdb) bt
#0 0x00007ffff7b9146f in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&)()
from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#1 0x00000000004098ca in __gnu_cxx::new_allocator<std::string>::construct<std::string<std::string const&> > (this=0x7fffffffd878,
__p=0x7ffff7dc04e0 <vtable for std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >+64>)
at /usr/include/c++/4.8/ext/new_allocator.h:120
#2 0x00000000004070ca in std::allocator_traits<std::allocator<std::string> >::_S_construct<std::string<std::string const&> >(std::allocator<std::string>&, std::allocator_traits<std::allocator<std::string> >::__construct_helper*, (std::string<std::string const&>&&)...) (__a=..., __p=0x7ffff7dc04e0 <vtable for std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >+64>)
at /usr/include/c++/4.8/bits/alloc_traits.h:254
#3 0x000000000040572e in std::allocator_traits<std::allocator<std::string> >::construct<std::string<std::string const&> >(std::allocator<std::string>&, std::string<std::string const&>*, (std::string<std::string const&>&&)...) (__a=...,
__p=0x7ffff7dc04e0 <vtable for std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >+64>)
at /usr/include/c++/4.8/bits/alloc_traits.h:393
#4 0x0000000000404528 in std::vector<std::string, std::allocator<std::string> >::push_back (this=0x7fffffffd878, __x="A")
at /usr/include/c++/4.8/bits/stl_vector.h:905
#5 0x0000000000403893 in Scheme::addAttr (this=0x7fffffffd878, newAttr="A") at Scheme.h:17
#6 0x000000000040207a in Database::evalSchemes (this=0x7fffffffd840, schemes=std::vector of length 1, capacity 1 = {...})
at Database.cpp:22
#7 0x000000000040c559 in main (argc=3, argv=0x7fffffffe238) at Main.cpp:26
(gdb)
由於trel
線並不完全像它在終端中執行,這裏是該輸出區域的屏幕截圖:
我真的很感謝你能提供的任何洞察力,因爲我完全失去了,部分原因是我不知道如何將第一個小問題稱爲有效的Google搜索。如果你能回答的只是第一個,那仍然是絕妙的。
嘗試簡化您的程序併發布您真正需要幫助的部分 – Pooya