重用字符串流而不需要重新分配

2024-01-03

我试图弄清楚如何重用 stringstream 对象,而无需每次在流中放入某些内容时都需要重新分配底层字符串。我已经发现这个答案 https://stackoverflow.com/questions/624260/how-to-reuse-an-ostringstream这导致我这样做:

int main() {

        stringstream ss;
        int x;
        ss << "423";
        ss >> x; // x is now 423

        ss.clear();
        ss.seekg(0);
        ss.seekp(0);

        ss << "1";
        ss >> x; // x is now 123. Instead I want x to be 1.

        std::cout << x << std::endl;
}

不幸的是,这不起作用,因为第一遍的字符串内容仍然存在(在第一遍之后,字符串是"423"在第二遍之后他们是"123")。但是,如果我在第二次放置之后添加一个空格,事情就会发生seem工作,像这样:

int main() {

        stringstream ss;
        int x;
        ss << "423";
        ss >> x; // x is now 423

        ss.clear();
        ss.seekg(0);
        ss.seekp(0);

        ss << "1";
        ss << " "; // add a space right after the desired value
        ss >> x; // x is now 1

        std::cout << x << std::endl;
}

第二遍之后,字符串是"1 3"。我对 I/O 库不太熟悉,我想知道上述方法是否安全,或者它是否恰好适用于这个简单的示例,或者是否有更好的解决方案。实时代码here http://coliru.stacked-crooked.com/a/0a9ecf8fd2abd00d。谢谢你!


我使用 clang 和以下代码进行了一些调查和实验:

测试代码

class LogHelper {
public:
    ~LogHelper() {
        std::cout << out.str() << '\n';
    }

    std::ostream &stream() {
        return out;
    }

private:
    std::ostringstream out;
};

#define LOG() LogHelper().stream() << __FUNCTION__ << '(' << __LINE__ << ")"
#define VAR(x) ", " #x "[" << x << ']'

class MyAllocator : public std::allocator<char> {
public:
    using base = allocator<value_type>;
    using base::allocator;

    value_type* allocate( std::size_t n, const void * hint) {
        LOG() << VAR(n);
        return base::allocate(n, hint);
    }

    value_type* allocate( std::size_t n ) {
        LOG() << VAR(n);
        return base::allocate(n);
    }

    void deallocate( value_type* p, std::size_t n ) {
        LOG() << VAR(n);
        base::deallocate(p, n);
    }
};

using MySStream = std::basic_stringstream<char, std::char_traits<char>, MyAllocator>;
using MyString = std::basic_string<char, std::char_traits<char>, MyAllocator>;

int main() {
    MySStream ss; // (MyString(255, '\0'));
    ss.clear();

    int x;
    ss << "423";
    ss << " 423";

    LOG();
    ss << " 423jlfskdfjl jfsd sdfdsfkdf dsfg dsfg dfg dfg dsfg df gdf gdfg dsfg dsfgdsfgds";
    LOG();
    ss >> x;

    ss.clear();
    ss.str({});

    ss.seekg(0);
    ss.seekp(0);

    ss << "1";
    ss >> x;

    std::cout << x << std::endl;
    LOG();

    return 0;
}
  • 你的渴望分配的例子clang https://wandbox.org/permlink/dIz5RLGNzq2BosLz, 视觉工作室 http://rextester.com/HXCJ27140, gcc 7.3 忽略自定义分配器 https://wandbox.org/permlink/HscWOqsur0HtCHdC, gcc 8.x 无法编译 https://wandbox.org/permlink/u2ygBmSJ96RNcUBg
main(55)
allocate(34), n[48]
allocate(34), n[96]
deallocate(39), n[48]
main(57)
1
main(70)
deallocate(39), n[96]
  • 在流上预设长字符串clang https://wandbox.org/permlink/MtHaWGuNnPkNokmn, 视觉工作室 http://rextester.com/MJKLG83660
allocate(34), n[256]
allocate(34), n[256]
deallocate(39), n[256]
main(55)
main(57)
1
main(70)
deallocate(39), n[256]

我有几个发现

  1. clang 和 Visual 的行为方式相同,但 gcc 对此代码存在一些严重问题。
  2. std::basic_stringstream字符串缓冲区总是增长,从不收缩
  3. std::basic_stringstream糟透了。您不能保留字符串大小或缓冲区大小,例如以防万一std::string。自定义分配器只能按类型传递,不能按对象提供分配器。
  4. 为了减少分配,您必须在请求时设置大字符串,然后直到您无法成功为止,它的容量重新分配将不会发生(第二个示例)。
  5. 提供自定义分配器并没有多大帮助,而且它在获取结果字符串时添加了样板代码。在我的示例中,它主要用于记录分配和释放。
  6. ss.str({});不引起分配。这里小字符串优化有帮助

结论:

  1. 你可以安全地做ss.str({});正如您链接中所建议的那样,答案不会导致分配。这里小字符串优化有帮助,事实上
  2. 自定义分配器不是很有帮助
  3. 在乞讨时设置大的虚拟字符串是非常有效的邪恶黑客
  4. 寻找替代方案应该是更好的方法(也许是提升 - 我没有测试它)
  5. Point 1你的问题表明你没有进行任何测量,你的问题是基于个人假设。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

重用字符串流而不需要重新分配 的相关文章

  • 如何将 std::string& 转换为 C# 引用字符串

    我正在尝试将 C 函数转换为std string参考C 我的 API 如下所示 void GetStringDemo std string str 理想情况下 我希望在 C 中看到类似的东西 void GetStringDemoWrap r
  • 在模板类中声明模板友元类时出现编译器错误

    我一直在尝试实现我自己的链表类以用于教学目的 我在迭代器声明中指定了 List 类作为友元 但它似乎无法编译 这些是我使用过的 3 个类的接口 Node h define null Node
  • 机器Epsilon精度差异

    我正在尝试计算 C 中双精度数和浮点数的机器 epsilon 值 作为学校作业的一部分 我在 Windows 7 64 位中使用 Cygwin 代码如下 include
  • 随着时间的推移,添加到 List 变得非常慢

    我正在解析一个大约有 1000 行的 html 表 我从一个字符串中添加 10 个字符串 td 每行到一个list td
  • 如何在 C# 中打开 Internet Explorer 属性窗口

    我正在开发一个 Windows 应用程序 我必须向用户提供一种通过打开 IE 设置窗口来更改代理设置的方法 Google Chrome 使用相同的方法 当您尝试更改 Chrome 中的代理设置时 它将打开 Internet Explorer
  • 从经典 ASP 调用 .Net C# DLL 方法

    我正在开发一个经典的 asp 项目 该项目需要将字符串发送到 DLL DLL 会将其序列化并发送到 Zebra 热敏打印机 我已经构建了我的 DLL 并使用它注册了regasm其次是 代码库这使得 IIS 能够识别它 虽然我可以设置我的对象
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • 用于 FTP 的文件系统观察器

    我怎样才能实现FileSystemWatcherFTP 位置 在 C 中 这个想法是 每当 FTP 位置添加任何内容时 我都希望将其复制到我的本地计算机 任何想法都会有所帮助 这是我之前问题的后续使用 NET 进行选择性 FTP 下载 ht
  • ASP.NET Core 3.1登录后如何获取用户信息

    我试图在登录 ASP NET Core 3 1 后获取用户信息 如姓名 电子邮件 id 等信息 这是我在登录操作中的代码 var claims new List
  • C# 列表通用扩展方法与非通用扩展方法

    这是一个简单的问题 我希望 集合类中有通用和非通用方法 例如List
  • 结构体的内存大小不同?

    为什么第一种情况不是12 测试环境 最新版本的 gcc 和 clang 64 位 Linux struct desc int parts int nr sizeof desc Output 16 struct desc int parts
  • 为什么这个字符串用AesCryptoServiceProvider第二次解密时不相等?

    我在 C VS2012 NET 4 5 中的文本加密和解密方面遇到问题 具体来说 当我加密并随后解密字符串时 输出与输入不同 然而 奇怪的是 如果我复制加密的输出并将其硬编码为字符串文字 解密就会起作用 以下代码示例说明了该问题 我究竟做错
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • C 函数 time() 如何处理秒的小数部分?

    The time 函数将返回自 1970 年以来的秒数 我想知道它如何对返回的秒数进行舍入 例如 对于100 4s 它会返回100还是101 有明确的定义吗 ISO C标准没有说太多 它只说time 回报 该实现对当前日历时间的最佳近似 结
  • 在 WPF 中使用 ReactiveUI 提供长时间运行命令反馈的正确方法

    我有一个 C WPF NET 4 5 应用程序 用户将用它来打开某些文件 然后 应用程序将经历很多动作 读取文件 通过许多插件和解析器传递它 这些文件可能相当大 gt 100MB 因此这可能需要一段时间 我想让用户了解 UI 中发生的情况
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • DotNetZip:如何提取文件,但忽略zip文件中的路径?

    尝试将文件提取到给定文件夹 忽略 zip 文件中的路径 但似乎没有办法 考虑到其中实现的所有其他好东西 这似乎是一个相当基本的要求 我缺少什么 代码是 using Ionic Zip ZipFile zf Ionic Zip ZipFile
  • 在OpenGL中,我可以在坐标(5, 5)处精确地绘制一个像素吗?

    我所说的 5 5 正是指第五行第五列 我发现使用屏幕坐标来绘制东西非常困难 OpenGL 中的所有坐标都是相对的 通常范围从 1 0 到 1 0 为什么阻止程序员使用屏幕坐标 窗口坐标如此严重 最简单的方法可能是通过以下方式设置投影以匹配渲
  • 指针和内存范围

    我已经用 C 语言编程有一段时间了 但对 C 语言还是很陌生 有时我对 C 处理内存的方式感到困惑 考虑以下有效的 C 代码片段 const char string void where is this pointer variable l

随机推荐

  • 防止 CHARACTER VARYING 字段中出现空字符串

    我正在使用 PostgreSQL 并希望阻止某些必需的 CHARACTER VARYING VARCHAR 字段允许空字符串输入 这些字段还需要包含唯一值 因此我已经使用了唯一约束 但是 这并不能阻止原始 唯一 空值 基本示例 其中用户名需
  • 如何使用 MFC 应用程序 (C++ Visual Studio 2010) 中的按钮更改图像的可见属性?

    我正在尝试制作一个程序 当按下应用程序中某个名为 隐藏 的按钮时 图像就会消失 我知道在 Windows 窗体应用程序中它会是这样的 pictureBox1 gt Visible true false 但该代码在 MFC 中不起作用 我在M
  • 函数指针有什么用,我将如何使用它们?

    我知道我可以使用函数指针 有人可以解释为什么要使用它们以及如何使用它们吗 简短的示例代码对我非常有帮助 一个简单的情况是这样的 根据您的业务逻辑 您有一系列操作 函数 您有一个哈希函数 可以将输入问题减少到业务逻辑函数之一 干净的代码将具有
  • 可以在 Node.JS Express 应用程序中插入中间件吗

    有没有办法在 Express 堆栈中注入中间件 我的意思是我想让我的 app js 设置主中间件链 然后调用传递应用程序实例的其他模块 他们可能想要插入更多中间件 例如想要在正确位置添加护照的身份验证模块 你一定可以通过你的app对象其他模
  • 从 Option[] 包装的对象中读取多个变量

    我有一个变量obj Option MyObject 并希望从中提取多个变量 如果未设置对象 则应使用默认值 目前我是这样做的 val var1 obj match case Some o gt e var1 case gt default1
  • 如何通过包含部分字符串的组件名称查询组件

    我想用Ext ComponentQuery query 查询包含某个名称路径的按钮名称 假设我有 4 个按钮 名称声明为 edit btn add btn add2 btn 和 edit2 btn 然后我使用查询 Ext Component
  • Sass --watch 不重新编译

    Sass 更新了我的主样式表build css当我将更改保存到build scss 但不会更新build css例如 当我保存对任何部分的更改时 grid settings scss 我基本上必须手动重新保存build scss每次我对部分
  • 如何在西门子 S7-1200 和 python 之间进行通信?

    我正在 S7 1200 plc 上运行一个进程 我需要它向我的 python 脚本发送启动信号 脚本运行完成后 需要将一些内容发送回 plc 以启动下一阶段 哦 它必须在梯子上完成 有没有一种快速而肮脏的方式通过profibus发送东西 或
  • 如何在 Sublime Text 2 中删除包

    我想删除和 或停用EmmetSublime Text 2 中的包 我应该删除Emmet目录或删除包的典型工作流程是什么 If you installed with package control search for Package Con
  • 未找到符号,应位于:平面命名空间

    我有一个巨大的gl pxd包含所有定义的文件gl h glu h and glut h 例如它有这些行 cdef extern from
  • 为什么 cffi 比 numpy 快这么多?

    我一直在尝试用 python 编写 cffi 模块 它们的速度让我想知道我是否正确使用了标准 python 这让我想彻底转向C 说实话 有一些很棒的 python 库我永远无法用 C 重新实现自己 所以这比任何实际情况都更假设 此示例显示了
  • 如何保持 PHP“查看源代码”html 输出干净[重复]

    这个问题在这里已经有答案了 今天在网站上查看源代码后 这一直困扰着我 我在模板中使用 PHP 输出来获取动态内容 模板仅以 html 形式开始 并且缩进和格式清晰 然后添加 PHP 内容并缩进以匹配 html 格式 ul li nav1 l
  • 如何在我的 iPhone 应用程序中使用 NSError?

    我正在努力捕获应用程序中的错误 并且正在考虑使用NSError 我对如何使用它以及如何填充它有点困惑 有人可以提供一个关于我如何填充然后使用的示例吗NSError 嗯 我通常做的是让我的方法在运行时可能会出错 并引用NSError指针 如果
  • 从 http://localhost/ 运行 file://

    我想知道如何使我的 html 项目不从 file 运行 而是作为本地主机运行 因为我实现的功能之一需要 getUserMedia 当从 file 加载时 浏览器会立即阻止该项目 我对此做了很多研究 但我仍然不明白应该如何做 所以如果可以的话
  • 如何加密cookie中的会话id?

    当我阅读有关会话劫持的文章时 我了解到对存储在 cookie 中的会话 ID 值进行加密会很好 据我所知 当我通过调用开始会话时session start PHP 不会加密 cookie 中的会话 id 值 如何加密会话 ID 值 然后用它
  • 添加和删​​除类不同的元素

    所以我目前正在学习 jquery 和一点动画的 tweenlite 我想保持基本 所以我目前正在构建一个投资组合网格 但我想添加一个元素的点击 另一个元素正在淡入 从右侧滑动并不重要 但是我找不到一种方法来使其工作 即 1 个元素有 1 个
  • 设置使用 anaconda 与 VS Code 和集成 Git 终端时卡住

    我想学习数据科学 所以使用了一些非常流行的 Python 模块 如 Pandas Matplotlib Numpy 等 所以我清理安装了 Anaconda 现在使用它作为我的默认 Python 解释器 还使用 Conda 来安装包和创建虚拟
  • Httpclient multipart/form-data 同时发布图像和 json

    我正在尝试使用 C 代码在一个请求中上传图像和 json 但服务器总是返回 400 错误请求 使用 fiddler 执行相同的请求返回状态代码 200 帮助 这是我的小提琴手代码 WebKitFormBoundary7MA4YWxkTrZu
  • OkHTTP Websocket:连接上的蒸汽意外终止

    我正在尝试连接到 Stack Exchange 聊天 Websocket websocket 用于接收聊天中的新事件 例如新消息 以下是用于创建 Websocket 的代码 String wsUrl getWsUrl Request wsR
  • 重用字符串流而不需要重新分配

    我试图弄清楚如何重用 stringstream 对象 而无需每次在流中放入某些内容时都需要重新分配底层字符串 我已经发现这个答案 https stackoverflow com questions 624260 how to reuse a