繁体   English   中英

std :: string连接的运行时依赖性

[英]Runtime dependency for std::string concatenation

std::string sAttr("");
sAttr = sAttr+VAL_TAG_OPEN+sVal->c_str()+VAL_TAG_CLOSE;

否则在我定义的代码中

const char VAL_TAG_OPEN[]   = "<value>";

sVal是一个从字符串指针数组中检索的变量。 这在大多数系统,Windows和Linux中都能正常工作。 然而,在一个客户站点,我认为我们已经在哪个版本的linux上进行了一些广泛的测试,产生一个结果,好像我从未使用过VAL_TAG_OPENVAL_TAG_CLOSE 我收到的结果是

sAttr = sAttr+sVal->c_str();

这是怎么回事 ?。 std :: string连接是否因运行时而异?

为什么->c_str() 如果sValstd::string ,请尝试删除此调用。 请记住,评估的顺序是未定义的,因此您最终可能会添加指针而不是连接字符串,因为VAL_TAG_OPENsVal->c_str()VAL_TAG_CLOSE都是纯C字符串。 我建议你使用加法赋值运算符+= ,例如:

sAttr += VAL_TAG_OPEN;
sAttr += *sVal; /* sVal->c_str() ? */
sAttr += VAL_TAG_CLOSE;

(无论如何应该更快)。

不,std :: string连接绝对不应该依赖于运行时,但不知何故VAL_TAG_OPENVAL_TAG_CLOSE似乎是空字符串。

我猜你在某处有某种缓冲区溢出或无效指针运算,所以你的程序会覆盖包含那些“常量”值的内存。 无论你的记忆最终存在,确实是运行时(因此OS版本)。 过去通过切换编译器或优化器选项,我被类似的东西困住了。

正如你提到在原始数组中保留std :: string实例的原始指针一样,这样的错误确实不是不可能的,但可能很难检测,因为使用DEBUG构建不会给你任何迭代器检查所有这些全部到好东西......祝你好运。

我并不认为导致问题的评估顺序。 它是因为开头和结尾的常量字符数组

const char VAL_TAG_OPEN[]   = "<value>";
const char VAL_TAG_CLOSE[]  = "</value>"

连接运算符认为VAL_TAG_OPN和VAL_TAG_CLOSE不是空终止符字符串。 因此优化器只是忽略了他们认为它是垃圾。

sAttr += std::string(VAL_TAG_OPEN);
sAttr += *sVal;
sAttr += std::string(VAL_TAG_CLOSE);

这确实解决了它。

sAttr = sAttr+VAL_TAG_OPEN+sVal->c_str()+VAL_TAG_CLOSE;

就像fbonnet所说,这是评估问题的一个顺序。

如果该行从左到右严格评估,那么每次添加的结果都是一个std :: string对象,它有一个运算符重载以便添加,并且事情按预期工作。

如果它没有从左到右进行评估,那么你最终会将指针添加到一起,谁知道会给你带来什么。

避免使用此构造,只需在std :: string上使用+ =运算符即可。

暂无
暂无

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

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