Почему приведенный ниже код выдает ‘std::logic_error’ what(): basic_string::_M_construct null недопустимый?

#c #debugging #runtime-error #c 14

#c #отладка #ошибка во время выполнения #c 14

Вопрос:

Я получаю std::logic_error’ what(): basic_string::_M_construct null, недопустимый, когда я запускаю функцию sort_string с циклом for, но не с простым оператором отношения для сравнения двух строк. Программа создает наибольшее число из вектора заданных чисел. Для небольшого ввода он работает нормально, но не для большого ввода. Я предоставил входные данные ниже.

          #include<iostream>
         #include<string>
         #include<algorithm>
         #include<vector>

         bool sort_string(std::string x, std::string y) {

           std::string xy = x.append(y);
           std::string yx = y.append(x);


        //   For loop below, to calculate larger string gives "terminate called after throwing
        //   an instance of 'std::logic_error' what():  basic_string::_M_construct null not valid"
        //   Just comment the for loop and uncomment the last return statement to see


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

         for (int i = 0; i < xy.size(); i  ) {

              if (xy.at(i) > yx.at(i)) return true;
              if (yx.at(i) > xy.at(i)) return false;
         }
              return true;
       //-------------------------------------------------------------------------------------------------------

     /*
          This runs perfectly fine
     */

         //return xy>=yx;

        }
       
        int main() {
             int n;
             std::cin >> n;
             std::vector<std::string> arr(n);
             for (int i = 0; i < n; i  ) {
                   std::cin>>arr[i];
             }
             std::sort(arr.begin(), arr.end(), sort_string);
             for (int i = 0; i < n; i  ) {
                  std::cout << arr[i];
             }
             std::cout << std::endl;
         }
  

Инструкции:
Запуск с g -std=c 14

Ввод:

100

2 8 2 3 6 4 1 1 10 6 3 3 6 1 3 8 4 6 1 10 8 4 10 4 1 3 2 3 2 6 1 5 2 9 8 5 10 8 7 9 6 4 2 6 3 8 8 9 8 2 9 10 3 10 7 5 7 1 7 5 1 4 7 6 1 10 5 4 8 4 2 7 8 1 1 7 4 1 1 9 8 6 5 9 9 3 7 6 3 10 8 10 7 2 5 1 1 9 9 5

Комментарии:

1. Сбой, который я получаю, предполагает, что ваше сравнение не соответствует строгому слабому порядку.

2. Спасибо! Я не знал о строгом слабом упорядочении в функции сравнения сортировки. Теперь я понимаю. Еще одно сомнение смотрите в разделе комментариев @R Sahu.

Ответ №1:

Проблема вызвана

 return true;
  

в sort_string . Это должно быть

 return false;
  

Когда вы достигнете этой строки, xy будет равно yx . Следовательно, yx < xy есть false , а не true .

Строка

 return xy >= yx;
  

работает, потому что эта строка совпадает с

 return yx < xy;
  

Комментарии:

1. Как указал @Retired Ninja, это было из-за строгого упорядочения, так почему (return xy> =yx) работает, это из-за компилятора.

2. @dark_prince, как я указал в своем ответе, xy >= yx работает, потому что он такой же, как yx < xy . Это не имеет никакого отношения к компилятору. Что касается того, почему это работает для ввода небольшого размера, я не знаю.

3. ну, если xy==yx, то xy>=yx возвращает true так же, как для цикла, но xy>yx вернет false .

4. @dark_prince, с подробным кодом вы не достигнете return false; if yx != xy . Затем функция вернет форму внутри for цикла.

Ответ №2:

Ваш код будет работать, просто изменив return true вне for loop на return false . Однако я не понимаю, почему вы ТАК сильно усложняете этот код, когда вы могли бы просто сделать

 bool sort_string(const std::stringamp; x, const std::stringamp; y)
{
  return x > y;
}
  

Или даже реализовать его как лямбда.

Комментарии:

1. Да, это то, что я сделал в последнем операторе return (return xy>=yx). Мне нужно добавить обе строки перед сравнением.

2. Зачем вам нужно добавлять обе строки? Элементы в векторе должны измениться?

3. На самом деле код должен возвращать наибольшее число, сформированное из вектора заданных чисел, если я не добавлю их, он будет работать только для вектора однозначных чисел. Например: [4, 42] отсортирует вектор по [42,4], который выведет 424, но я хочу, чтобы [4,42] означало только 442.

4. Я понимаю. Ну, просто совет: вы должны передавать значения по ссылке, как в коде, который я предоставил. Копирование строк может быть очень дорогостоящим ресурсом. И вместо того, чтобы использовать x.append(y), вы могли бы просто сделать x y .