【问题标题】:Segment fault exception when try to add large number of elements to a static map尝试向静态地图添加大量元素时出现段错误异常
【发布时间】:2016-09-26 11:34:31
【问题描述】:

问题: 尝试向地图添加大量元素时出现段错误。

下面的程序运行良好,但是如果我向它添加大约 80000 个元素,它只会在运行时崩溃。根据我搜索的结果,这是由于程序可用的堆栈大小有限。任何解决方法?基本上我只需要保留一张 cityId 到 ~90000 个城市的城市名称的地图。

Utilities.hpp

#ifndef Utilities_hpp
#define Utilities_hpp
#include <string>
#include <map>

class Utilities {

public:
    typedef std::map<long, const char *> CityMap;
    static CityMap cityIdNameMap;

public:
    static std::string getCurrencySymbol(std::string &$currenyName);
    static const char *getCityFromId(long cityId);
    static CityMap createMap();
};
#endif /* Utilities_hpp */

Utilities.cpp

#include "Utilities.hpp"

Utilities::CityMap Utilities::cityIdNameMap = Utilities::createMap();

Utilities::CityMap Utilities::createMap() {
    CityMap tmpMap = {
        {1000010,"Abu Dhabi,Abu Dhabi,United Arab Emirates"},
        {1000010,"Abu Dhabi,Abu Dhabi,United Arab Emirates"},
        {1000011,"Ajman,Ajman,United Arab Emirates"}
    };

    return tmpMap;
}

// http://stackoverflow.com/questions/13464325/static-map-initialization
//class Utilities {
std::string Utilities::getCurrencySymbol(std::string &$currenyName) {
    return "$";
}

const char *Utilities::getCityFromId(long cityId) {
    return Utilities::cityIdNameMap[cityId];
}

ma​​in.cpp

#include <iostream>
#include <istream>
#include "Utilities.hpp"

using std::cout;
using std::endl;


int main(int argc, char *argv[])
{
    cout << Utilities::getCityFromId(1000011);

    return 0;
}

段故障日志:

System Integrity Protection: disabled

Crashed Thread:        0  Dispatch queue: com.apple.main-thread

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_PROTECTION_FAILURE at 0x00007fff57bf8ff8

VM Regions Near 0x7fff57bf8ff8:
MALLOC_SMALL           00007fbf5c000000-00007fbf5c800000 [ 8192K] rw-/rwx SM=PRV  
--> STACK GUARD            00007fff543f9000-00007fff57bf9000 [ 56.0M] ---/rwx SM=NUL  stack guard for thread 0
Stack                  00007fff57bf9000-00007fff583f9000 [ 8192K]   rw-/rwx SM=COW  thread 0

Application Specific Information:
/*********/CSVParser/DerivedData/Build/Products/Debug/./CSVParser

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   CSVParser                       0x00000001079e53a3 Utilities::createMap() + 1955795 (Utilities.cpp:13)

1   CSVParser                       0x0000000108da2384 __cxx_global_var_init + 20 (Utilities.cpp:11)

2   CSVParser                       0x0000000108da23b9 _GLOBAL__sub_I_Utilities.cpp + 9

3   dyld                            0x00007fff6bd6410b ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) + 265

4   dyld                            0x00007fff6bd64284 ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) + 40

5   dyld                            0x00007fff6bd608bd ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) + 305

6   dyld                            0x00007fff6bd60743 ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) + 127

7   dyld                            0x00007fff6bd609b3 ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) + 75

8   dyld                            0x00007fff6bd530f1 dyld::initializeMainExecutable() + 208

9   dyld                            0x00007fff6bd56d98 dyld::_main(macho_header const*, unsigned long, int, char const**, char const**, char const**, unsigned long*) + 3596

10  dyld                            0x00007fff6bd52276 dyldbootstrap::start(macho_header const*, int, char const**, long, macho_header const*, unsigned long*) + 512

11  dyld                            0x00007fff6bd52036 _dyld_start + 54

【问题讨论】:

  • 它在哪里产生段错误以及什么原因?
  • 你能给我们看看坏掉的代码吗?工作代码并不能真正帮助我们发现问题。
  • 请提供分段错误的堆栈跟踪..
  • 添加了段错误日志,正如我所说,当我在 createMap 函数中添加约 80k 个元素时,相同的程序崩溃。当然,所有元素都有不同的键。
  • 所以你的代码中嵌入了所有 80000 个字符串作为文字?将它们放入一个文件中,然后将其读入。

标签: c++ stdmap


【解决方案1】:

映射是在堆中分配的,但我猜正在发生的事情是初始化列表被分配在堆栈上,因此是段错误。

或者,您可以:

  1. 从文件中读取 ID 城市对,而不是对其进行硬编码。
  2. 如果您需要非常快的 createMap 性能,您可以尝试使用 boost::serialization 方法将映射序列化为二进制文件并反序列化 - 确保测量它是否真的更快。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 2014-09-16
    • 1970-01-01
    • 2020-01-13
    • 2021-08-05
    • 1970-01-01
    相关资源
    最近更新 更多