const string& 构造函数和模板化 std::set find 的分段错误

2024-01-15

以下代码遇到了段错误const string&构造函数,并以 0 退出string_view构造函数。我知道const string&这不是最好的方法。但根据我的理解,如果没有优化,临时string是由构造而成const char*,然后它的值被复制到Person构造函数被销毁之前。构造函数对我来说看起来有效。对于查找部分,set::find (string_view)将根据需要使用定义的 less 运算符。我没有看到这里有什么问题。我可以使用 g++-10 或 VS2022 重现该问题。

#include <set>
#include <iostream>
#include <string>
#include <string_view>
using namespace std;

struct Person{
    string name;
    Person(const string& s):name{s}{}
    //Person(string_view s):name{s}{}
    bool operator<(string_view s)const{
        return name<s;
    }
    bool operator<(const Person& o)const{
        return name<o.name;
    }
};
bool operator<(string_view s,const Person& p){
    return s<p.name;
}
set<Person,less<>>s;

int main(){
    s.emplace("hello");
    string_view hel="hel";
    auto res=s.find(hel);
}

gdb 为我提供了有关崩溃的以下信息:

Program received signal SIGSEGV, Segmentation fault.
0x000000000800280c in std::char_traits<char>::copy (__s1=0x7fffff7ef1c0 "\340\361~\377\377\177", __s2=0x7fffff7ef230 "hello",
    __n=<error reading variable: Cannot access memory at address 0x7fffff7eeff8>) at /usr/include/c++/10/bits/char_traits.h:401
401           copy(char_type* __s1, const char_type* __s2, size_t __n)

您的独立式operator<递归地调用自身(并且无限地)。这是因为没有内置的<比较一个的运算符string_view to a string,还有is隐式转换自string to const Person&.

虽然也有一个隐式转换string to string_view,因为函数本身的作用域/命名空间中有一个可用的转换,该转换是通过对两个操作数类型进行参数相关的查找找到的,而不是任何其他转换(感谢 Sam Varshavchik 指出了这一点)。

因此,在该函数体内,右侧操作数<比较被转换为const Person&,该函数因此调用自身。

要解决此问题,请将操作数转换为相同的 STL 类型;要么到 2string_view操作数,像这样:

bool operator<(string_view s, const Person& p)
{
    return s < string_view(p.name);
}

或 2string操作数,像这样:

bool operator<(string_view s, const Person& p)
{
    return string(s) < p.name;
}

注意:这不是一个特别容易发现的问题。但是,打开(完整)编译器警告可能会有所帮助。对于你的原始代码,MSVC 给了我这个:

警告 C4717:'operator

并且 clang 显示:

警告:通过此函数的所有路径都将调用自身 [-Winfinite-递归]

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

const string& 构造函数和模板化 std::set find 的分段错误 的相关文章

  • c和java语言中的换行符

    现在行分隔符取决于系统 但在 C 程序中我使用 n 作为行分隔符 无论我在 Windows 还是 Linux 中运行它都可以正常工作 为什么 在java中 我们必须使用 n 因为它与系统相关 那么为什么我们在c中使用 n 作为新行 而不管我
  • 在 C# 中创建具有单独列的分隔文本

    我一直在尝试在 C 中创建一个制表符限制的文本文件 以便数据正确显示在单独的列中 Firstname Lastname Age John Smith 17 James Sawyer 31 我尝试过 t 字符 但我得到的只是 Firstnam
  • 如何使用MemoryCache代替Timer来触发一个方法?

    以下方法通过等待已运行操作的结果来处理并发请求 对数据的请求可能会使用相同 不同的凭据同时出现 对于每组唯一的凭据 最多可以有一个GetCurrentInternal呼叫正在进行中 当准备就绪时 该呼叫的结果将返回给所有排队的服务员 pri
  • 使用Physics.Raycast 和Physics2D.Raycast 检测对象上的点击

    我的场景中有一个空的游戏对象 带有 2D 组件盒碰撞器 我将脚本附加到该游戏对象 void OnMouseDown Debug Log clic 但是当我点击我的游戏对象时 没有任何效果 你有什么想法 如何检测我的盒子碰撞器上的点击 使用光
  • 向 Nhibernate 发出 SQL 查询

    如何将此 SQL 查询发送给 Nhibernate SELECT Customer name FROM Company INNER JOIN Customer ON Company CompanyId Customer CompanyId
  • 读取文件特定行号的有效方法。 (奖励:Python 手册印刷错误)

    我有一个 100 GB 的文本文件 它是来自数据库的 BCP 转储 当我尝试导入它时BULK INSERT 我在第 219506324 行上收到一个神秘错误 在解决此问题之前 我想看看这一行 但可惜的是我最喜欢的方法 import line
  • 如何访问另一个窗体上的ListView控件

    当单击与 ListView 所在表单不同的表单中的按钮时 我试图填充 ListView 我在 Form1 中创建了一个方法以在 Form2 中使用 并将参数传递给 Form1 中的方法 然后填充 ListView 当我调试时 我得到了传递的
  • 生成(非常)大的非重复整数序列而不进行预洗牌

    背景 我编写了一个简单的媒体客户端 服务器 我想生成一个不明显的时间值 随从客户端到服务器的每个命令一起发送 时间戳中将包含相当多的数据 纳秒分辨率 即使它不是真正准确 因为现代操作系统中计时器采样的限制 等 我想做的 在 Linux 上
  • 关于在 Windows 上使用 WiFi Direct Api?

    我目前正在开发一个应用程序 我需要在其中创建链接 阅读 无线网络连接 在桌面应用程序 在 Windows 10 上 和平板电脑 Android 但无关紧要 之间 工作流程 按钮 gt 如果需要提升权限 gt 创建类似托管网络的 WiFi 网
  • 单击 form2 上的按钮触发 form 1 中的方法

    我对 Windows 窗体很陌生 我想知道是否可以通过单击表单 2 中的按钮来触发表单 1 中的方法 我的表格 1 有一个组合框 我的 Form 2 有一个 保存 按钮 我想要实现的是 当用户单击表单 2 中的 保存 时 我需要检查表单 1
  • 使用 JNI 从 Java 代码中检索 String 值的内存泄漏

    我使用 GetStringUTFChars 从使用 JNI 的 java 代码中检索字符串的值 并使用 ReleaseStringUTFChars 释放该字符串 当代码在 JRE 1 4 上运行时 不会出现内存泄漏 但如果相同的代码在 JR
  • Rx 中是否有与 Task.ContinueWith 运算符等效的操作?

    Rx 中是否有与 Task ContinueWith 运算符等效的操作 我正在将 Rx 与 Silverlight 一起使用 我正在使用 FromAsyncPattern 方法进行两个 Web 服务调用 并且我想这样做同步地 var o1
  • 使用 Moq 使用内部构造函数模拟类型

    我正在尝试模拟 Microsoft Sync Framework 中的一个类 它只有一个内部构造函数 当我尝试以下操作时 var fullEnumerationContextMock new Mock
  • 私有模板函数

    我有一堂课 C h class C private template
  • 有人可以提供一个使用 Amazon Web Services 的 itemsearch 的 C# 示例吗

    我正在尝试使用 Amazon Web Services 查询艺术家和标题信息并接收回专辑封面 使用 C 我找不到任何与此接近的示例 所有在线示例都已过时 并且不适用于 AWS 的较新版本 有一个开源项目CodePlex http www c
  • 如何对 Web Api 操作进行后调用?

    我创建了一个 Web API 操作 如下所示 HttpPost public void Load string siteName string providerName UserDetails userDetails implementat
  • (de)从 CSV 序列化为对象(或者最好是类型对象的列表)

    我是一名 C 程序员 试图学习 C 似乎有一些内置的对象序列化 但我在这里有点不知所措 我被要求将测试数据从 CSV 文件加载到对象集合中 CSV 比 xml 更受青睐 因为它更简单且更易于人类阅读 我们正在创建测试数据来运行单元测试 该集
  • 英特尔 Pin 与 C++14

    问题 我有一些关于在 C 14 或其他 C 版本中使用英特尔 Pin 的问题 使用较新版本从较旧的 C 编译代码很少会出现任何问题 但由于 Intel Pin 是操作指令级别的 如果我使用 C 11 或 C 14 编译它 是否会出现任何不良
  • 使用 GhostScript.NET 打印 PDF DPI 打印问题

    我在用GhostScript NET http ghostscriptnet codeplex com打印 PDF 当我以 96DPI 打印时 PDF 打印效果很好 但有点模糊 如果我尝试以 600DPI 打印文档 打印的页面会被极大地放大
  • 检查Windows控制台中是否按下了键[重复]

    这个问题在这里已经有答案了 可能的重复 C 控制台键盘事件 https stackoverflow com questions 2067893 c console keyboard events 我希望 Windows 控制台程序在按下某个

随机推荐