- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在为一个类(class)做一个编程作业,我遇到了一个非常奇怪的问题。技术问题是,当我尝试对特定 vector 执行任何操作时出现段错误,但它所在的对象和该对象所在的对象也表现得很奇怪。我怀疑这可能是一个简单的语法错误,我不知道如何最好地解决,所以让我们从它开始。如果此语法无效或仅半有效,您可能不需要阅读其余部分(除非更改它不起作用)。
无论如何,这是我关心的代码(在我的 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的构造函数。如果有更好的方法来做到这一点,那可能是我悲伤的原因,否则我担心最坏的情况,所以这里有一堆代码和终端输出:
元组.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 摘录):
#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
}
}
}
...
主要.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++ 进行编译,包括回溯的输出。第二个有更多信息,所以我评论了那个程序的 cout 结果。
如果我试图在修改之前清除 vector :
(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 搜索。如果您只能回答第一点,那仍然非常棒。
最佳答案
如果我跑题了,我深表歉意,但我相信 Database::getRel 中可能有一个问题:
return &relations.find(RelName)->second;
如果没有找到 RelName,find 函数可能会返回 map:end,并且 map::end 不应该被取消引用。您应该测试这种可能性并在这种情况下手动返回 NULL。
关于C++ 类未正确初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36512684/
这个问题已经有答案了: How to do case insensitive string comparison? (23 个回答) 已关闭 3 年前。 用户在我的输入栏中写入“足球”,然后执行第 6
啊,不习惯 javascript 中的字符串。 character_id= + id + correct= + correctOrIncorrect 这就是我需要制作成字符串的内容。如果您无法猜测字符
$(function() { var base_price = 0; CalculatePrice(); $(".math1").on('change', function(e) { Calc
我找不到任何文章回答问题:将Spinnaker部署到Spinnaker将管理的同一Kubernetes集群是否安全/正确?我主要是指生产,HA部署。 最佳答案 我认为Spinnaker和Kuberne
我正在使用MSVC在Windows上从源代码(官方源代码发布,而不是从仓库中)构建Qt5(Qt 5.15.0)。 我正在设置环境。变量,依赖项等,然后运行具有1600万个选项的configure,最后
我需要打印一个包含重复单词的数组。我的数组已经可以工作,但我不知道如何正确计算单词数。我已经知道,当我的索引计数器 (i) 为 49 时,并且当 (i) 想要计数到 50 时,我会收到错误,但我不知道
我正在遵循一个指南,该指南允许 Google map 屏幕根据屏幕尺寸禁用滚动。我唯一挣扎的部分是编写一个代码,当我手动调整屏幕大小时动态更改 True/False 值。 这是我按照说明操作的网站,但
我有一个类“FileButton”。它的目的是将文件链接到 JButton,FileButton 继承自 JButton。子类继承自此以使用链接到按钮的文件做有用的事情。 JingleCardButt
我的 friend 数组只返回一个数字而不是所有数字。 ($myfriends = 3) 应该是…… ($myfriends = 3 5 7 8 9 12). 如果我让它进入 while 循环……整个
这个问题在这里已经有了答案: Is there a workaround to make CSS classes with names that start with numbers valid?
我正在制作一个 JavaScript 函数,当调整窗口大小时,它会自动将 div 的大小调整为与窗口相同的宽度/高度。 该功能非常基本,但我注意到在调整窗口大小时出现明显的“绘制”滞后。在 JS fi
此问题的基本视觉效果可在 http://sevenx.de/demo/bootstrap-carousel/inc.carousel/tabbed-slider.html 获得。 - 如果你想看一看。
我明白,如果我想从函数返回一个字符串文字或一个数组,我应该将其声明为静态的,这样当被调用的函数被返回时,内容就不会“消亡”。 但我的问题是,当我在函数内部使用 malloc 分配内存时会怎样? 在下面
在 mySQL 数据库中存储 true/false/1/0 值最合适(读取数据消耗最少)的数据字段是什么? 我以前使用过一个字符长的 tinyint,但我不确定它是否是最佳解决方案? 谢谢! 最佳答案
我想一次读取并处理CSV文件第一行中的条目(例如打印)。我假设使用Unix风格的\n换行符,没有条目长度超过255个字符,并且(现在)在EOF之前有一个换行符。这意味着它是fgets()后跟strto
所以,我们都知道 -1 > 2u == true 的 C/C++ 有符号/无符号比较规则,并且我有一种情况,我想有效地实现“正确”比较。 我的问题是,考虑到人们熟悉的尽可能多的架构,哪种方法更有效。显
**摘要:**文章的标题看似自相矛盾。 本文分享自华为云社区《Java异常处理:如何写出“正确”但被编译器认为有语法错误的程序》,作者: Jerry Wang 。 文章的标题看似自相矛盾,然而我在“正
我有一个数据框,看起来像: dataDemo % mutate_each(funs(ifelse(. == '.', REF, as.character(.))), -POS) # POS REF
有人可以帮助我使用 VBScript 重新格式化/正确格式化带分隔符的文本文件吗? 我有一个文本文件 ^分界如下: AGREE^NAME^ADD1^ADD2^ADD3^ADD4^PCODE^BAL^A
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我是一名优秀的程序员,十分优秀!