试图用c++;,有时会变坏 我在学习java中的面向对象编程之后,对C++有了新的认识,所以我很难掌握内存分配。任务是创建一个加权有向图
我得到一个错误:“在抛出'std::bad_alloc'实例后调用terminate” what():std::bad_alloc“当我通过代码运行某些输入时,我很难找出是什么导致了它 我在谷歌上搜索了这个错误,发现它是内存问题,所以我试图检查我的代码并试图找到任何泄漏,但我不确定它们在哪里。大多数帖子都在谈论指针,我不打算实现指针,因为我不熟悉它们。谢谢你抽出时间试图用c++;,有时会变坏 我在学习java中的面向对象编程之后,对C++有了新的认识,所以我很难掌握内存分配。任务是创建一个加权有向图,c++,csv,memory,allocation,bad-alloc,C++,Csv,Memory,Allocation,Bad Alloc,我得到一个错误:“在抛出'std::bad_alloc'实例后调用terminate” what():std::bad_alloc“当我通过代码运行某些输入时,我很难找出是什么导致了它 我在谷歌上搜索了这个错误,发现它是内存问题,所以我试图检查我的代码并试图找到任何泄漏,但我不确定它们在哪里。大多数帖子都在谈论指针,我不打算实现指针,因为我不熟悉它们。谢谢你抽出时间 #include <iostream> #include <fstream> #include <s
#include <iostream>
#include <fstream>
#include <string>
#include <array>
#include <iterator>
#include <map>
#include <list>
#include <vector>
#include <algorithm>
using namespace std;
class WDGraph {
private:
map<string,map<string,int>> edges;
vector<string> verts;
list<string> leaves;
list<string> roots;
list<string> selfEdges;
public:
list<string> getRoots() { return roots; }
list<string> getLeaves() { return leaves; }
void addVert(string key) {
verts.push_back(key);
}
void link(string start, string dest, int cost) {
edges[start].insert(make_pair(dest,cost));
if (!containsLeaf(dest) && !containsVert(dest))
leaves.push_back(dest);
if (!containsRoot(start) && !containsVert(start))
roots.push_back(start);
if (start == dest)
selfEdges.push_back(start);
roots.remove(dest);
leaves.remove(start);
}
bool containsVert(string key) {
for (int i=0; i < verts.size(); i++) {
if (key == verts[i]) {
return true;
}
}
return false;
}
bool containsRoot(string key) {
bool found = (find(roots.begin(), roots.end(), key) != roots.end());
return found;
}
bool containsLeaf(string key) {
bool found = (find(leaves.begin(), leaves.end(), key) != leaves.end());
return found;
}
WDGraph() { }
void printWDG() {
cout << "Printing Weighted Directed Graph." << endl;
for (auto itr1 = edges.begin(); itr1 != edges.end(); ++itr1) {
for (auto itr2 = itr1->second.begin(); itr2 != itr1->second.end(); ++itr2) {
if (itr2->first == "null" && containsRoot(itr1->first)) {
cout << "[" << itr1->first << "]";
}
else if (itr2->first != "null")
cout << "[" << itr1->first << " -> ";
cout << itr2->first << ", " << itr2->second << "] ";
}
cout << "" << endl;
}
}
void printNumVerts() {
cout << "Total number of vertices: " << verts.size() << endl;
}
void printRoots() {
int num_roots = 0;
cout << "Vertices with zero inbound edges: " << endl;
for (auto itr = roots.begin(); itr != roots.end(); ++itr) {
cout << "[" << *itr << "]" << endl;
num_roots++;
}
if (num_roots == 0) cout << "None" << endl;
}
void printLeaves() {
int num_leaves = 0;
cout << "Vertices with zero outbound edges:" << endl;
for (auto itr = leaves.begin(); itr != leaves.end(); ++itr) {
if (*itr != "null")
cout << "[" << *itr << "]" << endl;
num_leaves++;
}
if (num_leaves == 0) cout << "None" << endl;
}
void printSelfEdges() {
cout << "Vertices with self edges:" << endl;
for (auto itr = selfEdges.begin(); itr != selfEdges.end(); ++itr) {
cout << "[" << *itr << "]" << endl;
}
}
};
int main() {
WDGraph myWDG;
string filePath;
string line;
int weight;
size_t commaPos;
vector<string> sVector;
ifstream dataFile;
// cout << "Please enter the relative path to an input file." << endl;
// getline (cin, filePath);
// cout << "The file path you entered was " << filePath << endl;
// dataFile.open(filePath);
dataFile.open("input.csv"); //test input
while (getline (dataFile, line)) {
commaPos = line.find(',');
//Parse input file into string vector
while (line.length() >= 1) {
if (line.length() == 1) {
sVector.push_back(line);
break;
}
sVector.push_back(line.substr(0,commaPos));
line = line.substr(commaPos+1);
commaPos = line.find(',');
}
//Create vertices depending on number of parameters
if (sVector.size() == 1) {
if (!myWDG.containsVert(sVector[0])) {
myWDG.addVert(sVector[0]);\
}
myWDG.link(sVector[0], "null", 0);
}
if (sVector.size() == 3) {
if (!myWDG.containsVert(sVector[0])) {
myWDG.addVert(sVector[0]);
}
if (!myWDG.containsVert(sVector[1])) {
myWDG.addVert(sVector[1]);
}
weight = stoi(sVector[2]);
myWDG.link(sVector[0], sVector[1], weight);
}
sVector.clear();
}
myWDG.printWDG();
myWDG.printNumVerts();
myWDG.printRoots();
myWDG.printLeaves();
myWDG.printSelfEdges();
}
但是,如果我有这样的东西,我会得到错误“在抛出'std::bad_alloc'实例后终止调用”:
Hello
World,Hello,3
My,Name,4
Is
Nikki,Hello,3
欢迎来到堆栈溢出。
提醒:抱歉这种风格,但你真的必须学会自己解决这类问题。这叫做调试。我是一名经验丰富的程序员,但我的代码从来没有像我第一次测试它时想象的那样运行。你需要学习如何使用像gdb
这样的调试器或Visua中的内置调试器l C++
环境
现在谈谈你的问题:
下面的代码接收到变量line
,其值为Hello
。行中没有,
字符,因此line=line.substr(commaPos+1);
始终返回Hello
,因为“Hello”字符串包含多个字符,所以您陷入了infinte循环
//Parse input file into string vector
while (line.length() >= 1) {
if (line.length() == 1) {
sVector.push_back(line);
break;
}
sVector.push_back(line.substr(0, commaPos));
line = line.substr(commaPos + 1);
commaPos = line.find(',');
}
问题并不止于此。由于在无限循环上的每次迭代都会导致程序执行:sVector.push_back(line.substr(0,commaPos))
实际上您分配了越来越多的内存,直到系统不再给这个过程更多的内存。这就是您得到错误分配
异常的原因。
换句话说,您的错误不是关于C++
,而是关于糟糕的编程
重新考虑您的程序,并思考如何处理像Hello
这样的边缘情况。
哦,不要在堆栈上构建对象。我知道有些地方声称在main
函数中这样做是可以的,但我相信这会造成很多麻烦。正如Z E Nir提到的,如果没有逗号,行解析代码将无法使用任何输入“,“排队。当然,您可以调试行解析代码,因为不管怎样,调试都是一项有价值的开发技能
但是,调试的一个可能的替代方法是找到一个现有的C++语言结构,它可以完成你想做的事情,并且是语言库的一部分,所以它已经被调试了。
通常,您想要做的是“普通的东西”,因此调试手动代码将花费比查找适当的预先存在的语言结构更多的时间,这要归功于您喜爱的internet搜索引擎和/或stackoverflow本身。能够快速找到语言结构也是一项非常有价值的技能
在您的例子中,函数getline()使用一个可选的分隔符,默认情况下是一个换行符,但您可以改为使用“,”作为分隔符,因此再次使用getline(),但要解析一行。它只需要一个字符串对象伪装成文件流,即std::istringstream对象
因此,您将得到两个嵌套循环,都使用getline():
#包括
while(getline(数据文件,行)){
std::istringstream iss{line};
字符串标记;
while(getline(iss,token,,')){
std::您是否尝试过调试?您将得到出现问题的线路泄漏很烦人,但不会直接导致错误分配。错误分配发生在内存分配失败时。一个原因可能是内存耗尽,但现在这意味着相当大的内存消耗。另一个原因可能是他请求的大小不切实际地高。如果大小是由缺少适当初始化的变量提供的,则可能会发生这种情况。因此,它提供的随机值可能意外足够或不够。一般来说,使用未初始化的变量对任何类型的零星错误都有好处。我会检查您是否有行解析代码E是正确的,因为它可能会永远循环并在内存中不断地添加相同的字符串。@妮科尔——请您考虑添加额外的标记,如“CSV”和“字符串解析”。对于您的问题?这是因为bad_alloc是一种症状,而不是您问题的根本原因。添加额外的标记将使其他用户更容易找到问题;谢谢!我们期待您将来对stackoverflow的贡献。@jpmarinier是的,当然!很抱歉,它将我限制为5个,我不确定哪些标记最相关。谢谢你们的提示!!谢谢你们的帮助!我一定会正确使用调试器。在这里询问之前,我很抱歉没有这样做。
//Parse input file into string vector
while (line.length() >= 1) {
if (line.length() == 1) {
sVector.push_back(line);
break;
}
sVector.push_back(line.substr(0, commaPos));
line = line.substr(commaPos + 1);
commaPos = line.find(',');
}
#include <sstream>
while (getline (dataFile, line)) {
std::istringstream iss{line};
std::string token;
while (getline (iss, token, ',')) {
std::cout << "DEBUG TOKEN LEN=" << token.length() << std::endl;
sVector.push_back(token);
}
// go build myWDG
}