通过std :: map进行第n次交互的Segfault

时间:2011-07-21 19:01:55

标签: c++ segmentation-fault stdmap

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

我的地图出现了分段错误。令我困惑的是,键上的n-1次迭代可以工作,但是第n次迭代时会出现seg错误。为了增加混淆,迭代seg故障的关键值在前一次迭代中找到(使用迭代器),甚至在代码中更早。

我试图用valgrind来描述seg错误,但是我得到了一个无限循环的消息,“信号11从线程0中删除”。因此,valgrind不是很有用。

seg faulting的地图称为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]++;
            }
        }

segfaults的情况是关键字“lcl_NM_000998”,试图找到关键字“lcl_NM_000999”。这没有意义,因为先前的getline()迭代找到键值“lcl_NM_000998”。我通过手动迭代地图来检查以确保是这种情况。

我已经检查过以前我的代码是不是以前的代码中的seg faulting,但令牌化看起来很好。在我的测试用例中,我的代码总是在这个位置发生段错误。有没有人有想法!?

1 个答案:

答案 0 :(得分:3)

这不仅仅是对存在感的测试

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

但也将节点插入到site_depths中,但在second成员中使用空指针。

该代码还相信startend始终在size给出的数组大小范围内。验证不会有害!