Сегфо по n-му целому через std :: map - PullRequest
3 голосов
/ 21 июля 2011

Решение: см. Пост Бо Перссона и мой комментарий ниже.

У меня ошибка сегментации с моей картой. Что меня смущает, так это то, что n-1 итераций над ключами работает, но затем выявляет ошибки на n-й итерации. Чтобы добавить к путанице, ключевое значение, в котором происходит сбой сегмента итерации, находится (с итератором) в предыдущей итерации и даже раньше в коде.

Я попытался профилировать ошибку сегмента с помощью valgrind, однако я получаю бесконечный цикл сообщения «сигнал 11 сбрасывается из потока 0». Следовательно, valgrind не очень полезен.

Карта, которая является ошибкой сегмента, называется 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 () и [] для значения ключа, которое вызывает ошибки (это также работает):

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

Затем, когда я анализирую текстовый файл, он вызывает ошибку при поиске () или, если я рекомендую, при доступе []:

            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". Я проверил, чтобы убедиться, что это так, вручную перебирая карту.

Я проверял, чтобы убедиться, что мой код раньше не был ошибочным в предыдущем коде, но токенизация выглядит нормально. Мой код всегда segfaults в этом месте в моем тестовом случае. У кого-нибудь есть идеи !?

1 Ответ

3 голосов
/ 21 июля 2011

Это не просто проверка на наличие

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

, но также вставка узла в site_depths, но с нулевым указателем в элементе second.

Код такжеполагает, что start и end всегда находятся в пределах диапазона размера массива, заданного size.Не мешало бы подтвердить это!

...