启用 g++ 优化会导致分段错误
Turning on g++ optimization leads to segmentation fault
我的程序在编译时使用以下内容时出现分段错误:
g++ -std=c++11 iForest.cpp -o iForest -O2
我已经阅读了这个线程 - 打开 g++ 优化会导致段错误 - 我不明白,但我认为我在那里没有犯同样的问题。我还检查了我的代码。我真的看不出哪里可能存在问题。请提供一些帮助。这是我的代码:
#include <bits/stdc++.h>
using namespace std;
class iTree{
public:
iTree(): root(NULL) {}
iTree(const vector<double>& _items): items(_items){}
iTree(const string &fname){ readData(fname); }
~iTree(){delete root;}
void print(){
for(int i = 0; i < np; ++i){
for(int j = 0; j < nd; ++j){
cout << items[i*nd + j] << " ";
}
cout << endl;
}
}
private:
int height, np, nd; //np: # of points, nd: # of dimensions of a point
vector<double> items; // items.size() = np*nd;
struct Node{
double val;
Node *left, *right;
int attri; // index of the attribute we pick
Node(): val(0.0), left(NULL), right(NULL), attri(-1) {}
~Node(){ delete left; delete right;}
} *root;
void readData(const string &fname){
ifstream ifs(fname);
ifs >> np >> nd;
items.resize(np*nd, 0.0);
for(int i = 0; i < np*nd; ++i) ifs >> items[i];
ifs.close();
}
};
int main(){
iTree forest("data.dat");
forest.print();
return 0;
}
当我使用 g++ -std=c++11 iForest.cpp -o iForest
编译时没有生成段错误。如果我不打印,也不会产生段错误。但是我认为我的 print() 函数中没有任何错误。
运行它,这是我使用的"数据.dat":
10 5
509304 9 0 2 1.0
509305 9 0 2 0.0
509306 9 0 2 0.0
509307 9 0 2 0.0
509308 9 0 2 0.0
509309 9 0 2 0.0
509310 9 0 2 0.0
509311 9 0 2 0.0
509312 9 0 2 0.0
509313 9 0 2 0.0
当您通过构造函数iTree(const string &fname){ readData(fname); }
输入时,您的类包含未初始化的变量root
(您在示例中这样做)。然后你的析构函数会delete root;
要解决此问题,您可以初始化root
,最简单的方法是将{}
放在其声明中的;
之前。
为了避免以后出现错误,最好将Node
和iTree
都声明为不可复制和不可移动,直到您准备好为它们实现复制操作。 默认的复制/移动行为将导致内存错误,因为违反规则三次。
这是更正后的程序,减少到一个文件(数据现在是一个嵌入的字符串,以使演示更容易)。
我嵌入了解释性注释。请注意关注点的分离,unique_ptr的使用,因此不需要析构函数。这反过来给了我自由移动的语义。
// note 8: include the proper headers
#include <vector>
#include <sstream>
#include <iostream>
#include <memory>
class iTree{
public:
iTree(): root(nullptr) {}
iTree(const std::vector<double>& _items): items(_items){}
// note 5: separate concerns - a tree needs to know nothing about files - only about istreams.
iTree(std::istream & is){ readData(is); }
// note 3: destructor now un-necessary
void print(){
for(int i = 0; i < np; ++i){
for(int j = 0; j < nd; ++j){
std::cout << items[i*nd + j] << " ";
}
std::cout << std::endl;
}
}
private:
int height, np, nd; //np: # of points, nd: # of dimensions of a point
std::vector<double> items; // items.size() = np*nd;
struct Node{
double val;
// note 1: unique_ptr instead of raw pointer
std::unique_ptr<Node> left, right;
int attri; // index of the attribute we pick
Node(): val(0.0), left(nullptr), right(nullptr), attri(-1) {}
// note 4: destructor now un-necessary
};
// note 2: unique_ptr instead of raw pointer
std::unique_ptr<Node> root;
void readData(std::istream &is){
is >> np >> nd;
items.resize(np*nd, 0.0);
for(int i = 0; i < np*nd; ++i) is >> items[i];
}
};
int main(){
static constexpr auto data =
R"data(10 5
509304 9 0 2 1.0
509305 9 0 2 0.0
509306 9 0 2 0.0
509307 9 0 2 0.0
509308 9 0 2 0.0
509309 9 0 2 0.0
509310 9 0 2 0.0
509311 9 0 2 0.0
509312 9 0 2 0.0
509313 9 0 2 0.0
)data";
// note 6: now I can express the entire example in one file - no need for a data file.
std::istringstream is(data);
// note 7: because I didnt define destuctors I now have move semantics for free
// which will be useful for performance and give me more expressive code.
auto forest = iTree(is);
forest.print();
return 0;
}
预期输出:
509304 9 0 2 1
509305 9 0 2 0
509306 9 0 2 0
509307 9 0 2 0
509308 9 0 2 0
509309 9 0 2 0
509310 9 0 2 0
509311 9 0 2 0
509312 9 0 2 0
509313 9 0 2 0
正如DeiDei在他的评论中所写,你删除了一些你没有分配的指针。我会更进一步说,你应该使用智能指针和 RAII 习语来消除这些问题。C-points通常会导致堆积如山的问题。此外,请使用nullptr
而不是NULL
宏。
编辑:要添加精度,请使用不可复制且只能移动的std::unique_ptr
,正如M.M在他的帖子中指出的那样。
- 在某些循环内使用vector.push_back时出现分段错误
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 当我的阵列太大时出现分段错误
- 分段错误当我试图运行程序时出错
- 在c++中初始化矩阵时出现分段错误(核心转储)
- 尝试使用集合函数时出现分段错误
- 我无法缩小此分段错误的原因
- g++的分段错误(在NaN上使用to_string两次时)
- 我是如何在这段代码中出现分段错误的
- 创建结构的数组时遇到分段错误
- 在c++中键入向量中的所有值后,得到分段错误(核心转储)
- 在 c++ 中实现 Trie 时出现分段错误
- 为什么 fstream 在打开带有格式的文件时会导致分段错误?
- 为什么我遇到分段错误?
- 动态类的分段错误(家庭作业问题)
- 分段错误 - 读取初始化指针的数组
- 如何摆脱C ++中的分段错误错误?
- 使用 CTYPE 时出现分段错误
- 为什么代码给出分段错误?