C++字符串字面值 vs. 常量字符串

7
我知道C/C++中的字符串字面量具有静态存储期,这意味着它们会“永久”存在于程序运行期间。因此,如果我有一个被频繁调用并使用字符串字面量的函数如下:
void foo(int val)
{
    std::stringstream s;
    s << val;
    lbl->set_label("Value: " + s.str());
}

在这里,set_label函数将以const std::string&作为参数。

我应该在这里使用const std::string而不是字符串字面量,或者它没有任何区别吗?

我需要尽可能地减少运行时内存消耗。

编辑:

我想比较字符串文字和在某种常量头文件中初始化的const std::string prefix("Value: ");

此外,这里的连接返回一个临时值(我们称之为Value: 42),并且将对此临时值的const引用传递给函数set_text(),我是正确的吗?

再次感谢!


你的魔球怎么说? - Edward Strange
如果您想要最小化运行时内存消耗,那么修改set_label函数以使用const char *和char *而不是string如何? - user347594
@user347594: 很遗憾,我无法修改set_label - Victor Parmar
@Noah:拥有一个const字符串将极大地提高代码的可维护性,但为了这个应用程序的内存优化,我会牺牲它,因此有了我的问题=) - Victor Parmar
由于您说这个函数被频繁调用,您可能不想使用非常慢的stringstream。请参见https://dev59.com/TG855IYBdhLWcg3wbjrO。 - Ben Voigt
此外,stringstream(以及stringbuf和所有其他支持机制)比char*std::string之间的差异更占用内存。 - Ben Voigt
4个回答

9
您的程序每次操作相同的字面量,这是最有效的存储形式。使用std::string将在函数运行时构造、在堆上复制,然后释放,这将是一种完全浪费的做法。

6
除非你知道原帖作者使用的实现方式,否则你无法确定这是否完全符合实际情况,也无法确定编译器优化是否会使你的陈述变得完全错误。 - Edward Strange
1
Noah是正确的,像这样的小字符串可能根本不使用堆存储。另一方面,stringstream非常笨重... - Ben Voigt
@Ben:我知道。OP指定了运行时内存使用情况,所以我真的不在意。 - Puppy
@Ben:std::string没有const char*的operator+重载吗?至于效率,有内存效率和时间效率。 - Puppy
@DeadMG:当然,问题中的代码将调用 operator+(const char*, std::string&),但由于它无法像模板那样推断长度,因此必须测量它,这至少会暂时使用比 std::string 更多的内存。两者之间内存使用的差异非常微小,我倾向于直接转向速度问题。 - Ben Voigt
显示剩余7条评论

2

如果您的编译器支持,使用snprintf可以减少内存使用并提高运行速度:

void foo(int val)
{
    char msg[32];
    lbl->set_label(std::string(msg, sprintf(msg, "Value: %d", val)));
}

如果想要更快的实现,请查看C++性能挑战:整数转换为std::string


+1 优化!但回到我的最初问题,使用字符串字面值是否比在常量头文件中定义的const std::string更高效? - Victor Parmar
@vic:这真的取决于您是否需要长度。std::string缓存了长度,因此只需读取变量即可,而对于char*,您必须使用迭代的strlen。但是,字符串字面值本身是一个字符数组,它将其长度作为编译时类型信息的一部分,这是最快的(当代码编写以利用它时)。 - Ben Voigt
你的答案中缺少一个括号。不过还是给你加1分。我喜欢这个解决方案。 - whoan
@whoan:感谢你让我知道这件事。 - Ben Voigt

0

你将如何构建你的const std::string?如果你是从某个字符串字面量中构建它,最终它只会变得更糟(或者如果编译器做得很好,则相同)。字符串字面量不会占用太多内存,并且是静态内存,这可能不是你所缺乏的内存类型。

如果你可以从文件中读取所有的字符串字面量,并在字符串不再使用时将内存归还给操作系统,那么可能有一些方法来减少内存占用(但这可能会大大降低程序的速度)。

但在执行此类操作之前,可能有许多其他方法可以减少内存消耗。


0

将它们存储在某种资源中,并根据需要加载/卸载它们。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接