c++ - 如何修复 SIGSEGV Segmentation fault 错误?
问题描述
我正在运行研究论文中的开源代码,遇到了分段错误错误。
我gdb
以前查看生成的core文件,用来bt full
了解更多关于哪里出了问题,但是我对c++非常陌生,所以我不知道如何使用给出的信息来进一步调试这个错误。
Program terminated with signal SIGSEGV, Segmentation fault.
#0 __GI_____strtof_l_internal (nptr=0x0, endptr=0x7ffecd484cd8, group=<optimized out>, loc=0x7f32914c5560 <_nl_global_locale>)
at strtod_l.c:609
609 strtod_l.c: No such file or directory.
(gdb) bt full
#0 __GI_____strtof_l_internal (nptr=0x0, endptr=0x7ffecd484cd8, group=<optimized out>, loc=0x7f32914c5560 <_nl_global_locale>)
at strtod_l.c:609
negative = 0
num = {0, 0, 0, 511101108348, 390842024046, 0, 0, 4, 18446744073709551504, 140732342488280}
numsize = 0
exponent = 0
base = 10
den = {140732342488280, 0, 4, 139855159296252, 139855168706208, 0, 14395410707824902144, 4, 140732342488288, 139855165608536}
densize = <optimized out>
retval = {206158430210}
bits = 0
cp = 0xffffffffffffffff <error: Cannot access memory at address 0xffffffffffffffff>
tp = <optimized out>
startp = <optimized out>
start_of_digits = <optimized out>
expp = <optimized out>
dig_no = <optimized out>
int_no = <optimized out>
lead_zero = <optimized out>
c = <optimized out>
decimal = 0x7f329128e7d8 <dot> "."
decimal_len = 1
thousands = 0x0
grouping = 0x0
cnt = <optimized out>
current = <optimized out>
__PRETTY_FUNCTION__ = "____strtof_l_internal"
lowc = <optimized out>
#1 0x0000562b2bf93133 in get_all_cooked_time_bw(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) ()
No symbol table info available.
#2 0x0000562b2bf8f2ab in main ()
No symbol table info available.
(gdb) quit
我猜这是出了问题的地方:
cp = 0xffffffffffffffff <error: Cannot access memory at address 0xffffffffffffffff>
,但我不知道cp
代表什么或在哪里以及如何解决这个问题。
以下是相关代码:
void split(const std::string &s, char delim, std::vector<std::string> &elems) {
std::stringstream ss;
ss.str(s);
std::string item;
while (std::getline(ss, item, delim)) {
elems.push_back(item);
}
}
std::vector<std::string> split(const std::string &s, char delim) {
std::vector<std::string> elems;
split(s, delim, elems);
return elems;
}
ALL_COOKED_TIME_BW get_all_cooked_time_bw(std::string path) {
ALL_COOKED_TIME_BW all_cooked_time_bw;
struct dirent *entry;
DIR *dir = opendir(path.c_str());
if (dir != NULL) {
while ((entry = readdir(dir)) != NULL) {
if (entry->d_name[0] == '.') continue; // read . or ..
std::string file_name = "";
file_name += COOKED_TRACE_FOLDER;
file_name += entry->d_name;
printf("%s\n", file_name.c_str());
std::ifstream in_file(file_name);
std::string line;
std::vector<float> cooked_time;
std::vector<float> cooked_bw;
if (in_file.is_open())
{
while ( getline (in_file, line) )
{
std::vector<std::string> parse = split(line, '\t');
cooked_time.push_back(std::stof(parse[0]));
cooked_bw.push_back(std::stof(parse[1]));
}
in_file.close();
}
all_cooked_time_bw.all_cooked_time.push_back(cooked_time);
all_cooked_time_bw.all_cooked_bw.push_back(cooked_bw);
all_cooked_time_bw.all_file_names.push_back(entry->d_name);
}
}
closedir(dir);
return all_cooked_time_bw;
}
解决方案
如果传递到split
此处的行不包含 2 个(或更多)元素:
std::vector<std::string> parse = split(line, '\t');
然后以下 2 行通过将无效字符串传递给std::stof
:
cooked_time.push_back(std::stof(parse[0]));
cooked_bw.push_back(std::stof(parse[1]));
这应该通过一些更具防御性的编程来解决:
if ( parse.size() != 2 )
{
throw std::invalid_argument("invalid file: " + file_name);
}
cooked_time.push_back(std::stof(parse[0]));
cooked_bw.push_back(std::stof(parse[1]));
在大多数情况下,您还应该将pos
参数传递给std::stof
,否则它会忽略字符串末尾的非数字字符。例如:
size_t pos;
cooked_time.push_back(std::stof(parse[0], &pos));
if (pos != parse[0].size())
{
throw std::invalid_argument("invalid file: " + file_name);
}
推荐阅读
- flutter - 因此,firebase_core ^0.7.0 与 cloud_firestore ^0.14.0 不兼容
- matlab - 包装 plot() 函数以使用 varargin
- angular - 在 Angular 和 RxJS 中的 http 调用后添加数据转换步骤
- javascript - 在反应中用滑块填充输入类型范围
- algorithm - 仅遍历序列的函数的跨度?
- flutter - 堆栈元素颤动中的相对定位,不同方向(纵向/横向)没有变化
- vb.net - 使用 SMS AT 命令的错误消息
- python - 为什么我在 python 中的循环出现索引错误?
- web-scraping - HTTP 请求 403 状态,复制的 chrome 标头
- python - 在大括号 {,} 中垂直打印