c++ - 通过 std::map 进行第 n 次交互时出现段错误

标签 c++ segmentation-fault stdmap

解决方案:请参阅 Bo Persson 的帖子和我在下面的评论。

我的 map 出现分割错误。令我困惑的是,对键的 n-1 次迭代有效,但随后在第 n 次迭代时出现段错误。更令人困惑的是,迭代段出错的关键值在上一次迭代中甚至在代码中更早的地方被发现(使用迭代器)。

我试图用 valgrind 分析 seg 错误,但是我收到消息的无限循环,“信号 11 从线程 0 中删除”。因此,valgrind 不是很有用。

出现段错误的 map 称为 site_depths。以下是值的插入方式:

map<string,unsigned short*> site_depths;
map<string,unsigned int>::iterator it;
map<string,unsigned short*>::iterator insert_it;
unsigned int size = 0;
string key = "";

// go through each key pair of CHROM_SIZES to build the site_depth map
for (it=CHROM_SIZES.begin(); it != CHROM_SIZES.end(); it++) {
    key = it->first;
    size = it->second;

    unsigned short *array = new unsigned short[size];

    insert_it = site_depths.end();
    site_depths.insert(insert_it, pair<string,unsigned short*>(key,array));
}

我已检查以确保所有附加值都有效。键和大小都打印到控制台。

紧接着,我测试 find() 和 [] 访问是否对 seg 错误的键值有效(这也有效):

cout << "schill found: " << site_depths.find("lcl_NM_000999")->first << endl;
unsigned short* test_array = site_depths["lcl_NM_000999"];

然后当我解析文本文件时,它将在 find() 上出现段错误,或者如果我推荐它,在 [] 访问上:

            string line;
            string chromosome;
            unsigned int start;
            unsigned int end;
            unsigned int i;
            char* values[3];
            unsigned short* sites;
            map<string,unsigned short*>::iterator iter_end = site_depths.end();

        while (getline(in,line)) {
            //use C strtok to tokenize the line
            char cstr[line.size()+1];
            strcpy(cstr,line.c_str());

            char *pch = strtok(cstr, "  ");

            // tokenize three columns
            for (i=0; i<3 || pch != NULL; i++) {
                values[i] = pch;
                pch = strtok(NULL, "    ");
            }

            chromosome = values[0];
            start = atoi(values[1])-1;  //must subtract 1 to correspond to 0 index
            end = atoi(values[2])-1;

            // get appropriate array pointer
            if (site_depths.find(chromosome) == iter_end) {
                cerr << "WARNING: Chromosome name in Input file does not match .len file." << endl;
                cerr << " Exiting script." << endl;
                exit(EXIT_FAILURE);
            }
            sites = site_depths[chromosome];

            // increment over range
            for (i=start; i<end; i++) {
                sites[i]++;
            }
        }

段错误发生在键“lcl_NM_000998”上,试图找到键“lcl_NM_000999”。这没有意义,因为之前的 getline() 迭代找到了键值“lcl_NM_000998”。我已通过手动遍历 map 来确认情况是否如此。

我已经检查以确保我之前的代码在之前的代码中没有段错误,但标记化看起来很好。在我的测试用例中,我的代码总是在这个位置出现段错误。有没有人有想法!?

最佳答案

这不仅仅是存在感的测试

unsigned short* test_array = site_depths["lcl_NM_000999"];

但也将一个节点插入到 site_depths 中,但在 second 成员中有一个空指针。

代码还相信 startend 始终在 size 给定的数组大小范围内。验证这一点不会有什么坏处!

关于c++ - 通过 std::map 进行第 n 次交互时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6781287/

相关文章:

c++ - 使用不等于与等于时是否有任何性能差异

c - fscanf() 导致段错误

c - 收到 Seg Fault 11 错误,但不知道原因

c++ - 从 std::map 中找到具有最大值的元素

python - 如何使用 Boost.Python 使用带有 std::map 或 std::vector 参数的构造函数来包装 C++ 类?

c++ - 计算C++的军事时间时差

c++ - 这些宏定义的目的是什么?

android - 对于 Android Studio NDK Gradle,如何为不同的文件设置不同的 cFlags?

c++ - 在 C++ 和 Linux 中追踪总线错误/段故障时遇到问题

c++ - 如何使用列表初始化来初始化 `std::map<std::string, CodeInfo>`?