为啥下面的代码给出 'std::logic_error' what(): basic_string::_M_construct null not valid?

Posted

技术标签:

【中文标题】为啥下面的代码给出 \'std::logic_error\' what(): basic_string::_M_construct null not valid?【英文标题】:Why does the below code give 'std::logic_error' what(): basic_string::_M_construct null not valid?为什么下面的代码给出 'std::logic_error' what(): basic_string::_M_construct null not valid? 【发布时间】:2020-09-01 03:01:21 【问题描述】:

当我使用 for 循环而不是使用简单的关系运算符来比较两个字符串时,我得到 std::logic_error' what(): basic_string::_M_construct null not valid 当我运行函数 sort_string 时。 该程序从给定数字的向量构造最大的数字。对于小输入,它工作正常,但不适用于大输入。我在下面提供了输入。

         #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

【问题讨论】:

我得到的崩溃表明您的比较不遵守严格的弱排序。 谢谢!我不知道 sort 的比较函数中的严格弱排序。我现在明白了。还有一个疑问请参阅@R Sahu 评论部分。 【参考方案1】:

问题是由

引起的
return true;

sort_string。应该是

return false;

当您到达那条线时,xy 等于yx。因此yx &lt; xyfalse,而不是true

线

return xy >= yx;

有效,因为该行与

return yx < xy;

【讨论】:

就像@Retired Ninja 指出的那样,这是因为严格的排序,所以为什么 (return xy>=yx) 起作用是因为编译器。 @dark_prince,正如我在回答中指出的那样,xy &gt;= yx 有效,因为它与yx &lt; xy 相同。它与编译器无关。至于为什么它适用于小尺寸输入,我不知道。 如果 xy==yx 那么 xy>=yx 返回 true 与 for 循环相同,但 xy>yx 将返回 false。 @dark_prince,详细的代码,如果yx != xy,你将无法到达return false;。然后,该函数将在for 循环内返回表单。【参考方案2】:

您的代码只需将for loop 之外的return true 更改为return false 即可工作。但是,我不明白为什么您可以简单地执行此代码 SO 这么复杂

bool sort_string(const std::string& x, const std::string& y)

  return x > y;

甚至可以将其实现为 lambda。

【讨论】:

是的,这就是我在最后一个 return 语句中所做的 (return xy>=yx)。我需要在比较之前附加两个字符串。 为什么需要附加两个字符串?向量中的元素应该改变吗? 实际上,如果我不附加它们,代码应该返回由给定数字向量形成的最大数字,它只适用于单个数字的向量。例如: [4, 42] 将向量排序为 [42,4] 将打印 424 但我希望 [4,42] 仅表示 442。 我明白了。好吧,只是一个建议:您应该像我提供的代码一样通过引用传递值。字符串可能是非常昂贵的复制资源。而不是使用 x.append(y),你可以简单地做 x + y。

以上是关于为啥下面的代码给出 'std::logic_error' what(): basic_string::_M_construct null not valid?的主要内容,如果未能解决你的问题,请参考以下文章

在javascript中,为啥这个数组的reduce方法在下面的代码中给出了这个输出?

为啥 python profiler 给出了矛盾的结果?

为啥对非指针结构进行类型转换会给出语法错误

为啥 Integer.MIN_VALUE 的负数给出相同的值? [复制]

为啥 Johnson-SU 分布在 scipy.stats 中没有给出正偏度?

为啥下面的代码会产生死锁