巨大的 initializer_list 编译分段错误

Posted

技术标签:

【中文标题】巨大的 initializer_list 编译分段错误【英文标题】:Huge initializer_list compilation segmentation fault 【发布时间】:2018-06-08 10:36:09 【问题描述】:
    const QHash<QString, float> idfs = "the", 0.0023450551861261,
    "of", 0.00258603321106053,
    "to", 0.00375511856396871,
    "and", 0.0040408455383457

..293060 多行

编译命令:/usr/local/bin/mpic++ -DQT_CORE_LIB -DQT_NO_DEBUG --isystem /usr/include/x86_64-linux-gnu/qt5 -isystem /usr/include/x86_64-linux-gnu/qt5/QtCore -isystem /usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++-64 -Wall -Wextra -std=c++11 -O2 -fPIC -fPIC -o CMakeFiles/antiplagiarism.dir/src/idfs.cc.o -c /home/user/newanalyzer/common/src/idfs.cc

编译结果:g++: internal compiler error: Segmentation fault (program cc1plus)

gcc 可以有庞大的初始化列表吗?

gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9) 

【问题讨论】:

我怀疑输入是否适合浮点数 可能是分段错误的原因吗?精确不是这里的问题 293060 行 x 2?如果这将在堆栈上进行,那将是一个......这个网站的名称是什么? "gcc 可以有庞大的初始化列表吗?"显然不是。您在答案中寻找什么样的信息? 好的替代品称为数据库 【参考方案1】:

gcc 可以有庞大的初始化列表吗?

是的。它太大以至于您构建的系统耗尽资源是不行的。 gcc 的架构没有固有的限制。

但这是静态数据,QHash 不适合这项工作。您应该使用 gperf 之类的东西和用户提供的结构。

在您的情况下,gperf 的输入文件如下所示:

 %language=C++
 %struct-type
 %define class-name WordHash
 %define slot-name text
 struct Word  const char *text; double frequency; ;
 %%
 the, 0.0023450551861261
 of, 0.00258603321106053
 to, 0.00375511856396871
 and, 0.0040408455383457

使用 gperf 生成的代码,您会查找如下:

double getFrequency(const char *text) 
  auto *word = WordHash::in_word_set(text, strlen(text));
  Q_ASSERT(!word || strcmp(word->text, text) == 0);
  return word ? word->frequency : -1;

【讨论】:

我已经尝试过 gperf,它使用 '-f 0' 选项运行超过 1 天,太长了。【参考方案2】:

向 gcc 提交了错误 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86118 问题已通过使用排序数组和二分查找解决。

【讨论】:

在那个错误报告中,你没有说这个问题是否也存在于更新的 gcc 版本中......【参考方案3】:

gcc 可以有庞大的初始化列表吗?

没有。

相反,将数据格式化为 JSON 对象数组(或作为具有 "key" : value 对的对象)。您可以使用一些简单的正则表达式命令(或修改您用来生成初始化列表的任何内容)快速完成此操作。 QT has JSON 支持。

如果您必须在程序中包含数据(而不是作为一个单独的 .json 文件以便于更新),则将该文件作为 const char* 定义嵌入。

【讨论】:

以上是关于巨大的 initializer_list 编译分段错误的主要内容,如果未能解决你的问题,请参考以下文章

带有 initializer_list 的编译时查找表

std::initializer_list 私有构造函数是不是从编译器得到非常特殊的处理?

在 Visual C++ 编译器中使用 std::initializer_list 2012 年 11 月 CTP

巨大的数组导致分段错误[重复]

使用 std::initializer_list 创建指向 std::min 的函数指针

Cannot open include file: 'initializer_list': No such file or directory