繁体   English   中英

操作数中不应存在 substring 导致 std::string 通过 + 运算符连接返回空字符串

[英]The substring shouldnotexist in an operand causes std::string concatenation by + operator to return an empty string

背景 - 我正在编写一个基准来测量丢失文件的stat成本,并将字符串“shouldNotExist”附加到文件路径的末尾以执行此操作。

例如/foo应该变成/fooshouldNotExist

但是,代码只是试图统计一个空字符串“”。

在深入挖掘之后,我注意到当使用+运算符连接两个std::string类型时,如果结果没有立即存储在std::string中,则结果是一个空字符串。 例如,在下面的代码中,我将其包裹在括号中并转换为 c_str()。

我正在使用g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0

#include <stdio.h>
#include <string>
int main() {
    const char *path, *x, *y;
    std::string a = "abcd";
    std::string result;

    path = (a + std::string("shouldnotexist")).c_str();
    printf("path is [%s]\n", path); // path is []

    x = std::string("shouldnotexist").c_str();
    printf("x is [%s]\n", x); // path is [shouldnotexist]

    y = (std::string("hello") + x).c_str();
    printf("y is [%s]\n", y); // path is []

    path = (a + std::string("fooo")).c_str();
    printf("path is [%s]\n", path); // path is [abcdfoo]

    path = (a + std::string("foooshouldnotexist")).c_str();
    printf("path is [%s]\n", path); //path is []

    path = (std::string("fooshouldnotexist") + a).c_str();
    printf("path is [%s]\n", path); // path is []

    result = std::string("fooshouldnotexist") + a;
    // Storing in an intermediate std::string appears to work
    // path is [fooshouldnotexistabcd], length is 21
    printf("path is [%s], length is %lu\n", result.c_str(), result.length());

    return 0;
}

您是否观察到类似的结果? 如果是这样,为什么会发生这种情况?它是否记录在任何地方?

c_str为您提供一个指向字符串实例内容的指针,以便在纯 C 函数(如 printf)中使用。 但是,当您将它应用于由例如连接创建的临时字符串实例时,它会立即失效,因为临时 object 超出 scope:

  1. 创建连接字符串的临时字符串实例: std::string _temporary = a + std::string("shouldnotexist");
  2. 在其上调用c_str方法,存储结果: path = _temporary.c_str()
  3. 临时实例退出 scope,删除字符串,使存储在path中的指针无效。
  4. 您对printf使用现在无效的存储指针。

在您编写时,通过将临时实例存储在变量中,问题就消失了,因为现在该实例在 printf 之前的 scope 中不会出现 go,从而保持指针有效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM