Почему `std :: sort` пытается сравнить значения, которых нет в списке ввода?

0

Я использую метод, объясненный здесь. Как получить перестановку индекса после сортировки, чтобы найти перестановку индекса, которая сортирует элементы массива.

Как ни странно, в некоторых случаях я получаю ошибки сегментации. Отслеживая проблему, я обнаружил, что std::sort пытается вызвать компаратор с индексами за пределами допустимого диапазона. Я уверен, что всегда перед вызовом std::sort массив index заполняется правильными индексами (например, 0 to data.size()-1).

Интересно отметить, что в моем случае data всегда имеют длину 32 и я понимаю, что компаратор вызывается с первым аргументом 145 (а второй всегда является чем-то в диапазоне от 0 до 31).

Любая идея, почему это может произойти?

Вот код:

class compare {
      private:        
         const double* list;
      public:
         compare(const double* d): list(d) {}
         bool operator()(const size_t& a, const size_t& b) {
               // indeed I observe that this function gets called with a = 145 and b in 
               // the range of 0 to 31

              return (list[a] < list[b]);
         }
  };

std::vector<double> data(32);
std::vector<size_t> idx(32);

compare cmp(&data[0]);
size_t i;

// populate the data array ... for example:
for (i = 0; i < 32; i++)
    data[i] = 1.0 * (rand() % 100) / 50; 

for (i = 0; i < 32; i++)
  idx[i] = i;
std::sort(idx.begin(), idx.end(), cmp);
  • 4
    Покажите нам код
  • 1
    Пожалуйста, опубликуйте тестовый пример, чтобы продемонстрировать проблему. Мы не можем догадаться, что делает ваш код.
Показать ещё 16 комментариев
Теги:
sorting
std

1 ответ

3

Я не могу воспроизвести то, что вы наблюдаете. Вот очищенная версия вашего кода, которая, кажется, работает нормально (gcc и clang).

#include <vector>
#include <algorithm>
#include <stdexcept>

#include <cstdlib>
#include <cstdio>

#define LSIZE 32

// ------------------------------------------------------------------------

class compare 
{
private:        
    const double* ptr;

public:

    compare(): ptr(0) {}
    compare( const double* d ): ptr(d) {}

    bool operator()( size_t a, size_t b ) 
    {
        if ( ptr == 0 ) throw std::runtime_error("Null pointer to data.");
        if ( a >= LSIZE || b >= LSIZE ) throw std::out_of_range("Index out of range.");

        // Uncomment to show the comparisons:
        // printf( "Comparing data[%lu] (%.2f) and data[%lu] (%.2f)\n", 
        //      a, ptr[a], b, ptr[b] );

        return ptr[a] < ptr[b];
    }
};

// ------------------------------------------------------------------------

int main()
{
    std::vector<double> data(LSIZE);
    std::vector<size_t> idx(LSIZE);

    for ( unsigned i=0; i<LSIZE; ++i )
    {
        idx[i]  = i;
        data[i] = 1.0 * (rand() % 100) / 50; 
    }

    std::sort( idx.begin(), idx.end(), compare( data.data() ) );
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню