简体   繁体   English

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

[英]Runtime dependency for std::string concatenation

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

else where in the code I have defined 否则在我定义的代码中

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

sVal is a variable that is retrieved off of a array of string pointers. sVal是一个从字符串指针数组中检索的变量。 This works fine in most of the system, windows and linux. 这在大多数系统,Windows和Linux中都能正常工作。 However at a customer site, where to my belief has a version of linux on which we had done some extensive testing, produce a result as if I have never used the VAL_TAG_OPEN and VAL_TAG_CLOSE . 然而,在一个客户站点,我认为我们已经在哪个版本的linux上进行了一些广泛的测试,产生一个结果,好像我从未使用过VAL_TAG_OPENVAL_TAG_CLOSE The results I recieve is for 我收到的结果是

sAttr = sAttr+sVal->c_str();

Whats going on ?. 这是怎么回事 ?。 Does std::string concatenation varies across runtime ? std :: string连接是否因运行时而异?

Why the ->c_str() ? 为什么->c_str() If sVal is a std::string , try removing this call. 如果sValstd::string ,请尝试删除此调用。 Remember that the order of evaluation is undefined, so you may end up adding pointers instead of concatenating strings, because VAL_TAG_OPEN , sVal->c_str() and VAL_TAG_CLOSE are all plain C strings. 请记住,评估的顺序是未定义的,因此您最终可能会添加指针而不是连接字符串,因为VAL_TAG_OPENsVal->c_str()VAL_TAG_CLOSE都是纯C字符串。 I suggest you use the addition assignment operator += , eg : 我建议你使用加法赋值运算符+= ,例如:

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

(which should be faster anyway). (无论如何应该更快)。

No, std::string concatenation should definitely not depend upon runtime, but somehow VAL_TAG_OPEN and VAL_TAG_CLOSE seem to be empty strings. 不,std :: string连接绝对不应该依赖于运行时,但不知何故VAL_TAG_OPENVAL_TAG_CLOSE似乎是空字符串。

I'd guess you've some kind of buffer overflow or invalid pointer arithmetic somewhere, so that your program overwrites the memory containing those "constant" values. 我猜你在某处有某种缓冲区溢出或无效指针运算,所以你的程序会覆盖包含那些“常量”值的内存。 Wherever your memory ends up being is indeed runtime (and therefore OS version) specific. 无论你的记忆最终存在,确实是运行时(因此OS版本)。 I've been trapped by similar things in the past by switching compilers or optimizer options. 过去通过切换编译器或优化器选项,我被类似的东西困住了。

As you mention keeping raw pointers to std::string instances in raw arrays, such errors are indeed not all to improbable, but may be difficult to detect, as using a DEBUG build won't give you any iterator checks with all these all to RAW things... Good luck. 正如你提到在原始数组中保留std :: string实例的原始指针一样,这样的错误确实不是不可能的,但可能很难检测,因为使用DEBUG构建不会给你任何迭代器检查所有这些全部到好东西......祝你好运。

I don't thing its the order of evaluation that is causing the issue. 我并不认为导致问题的评估顺序。 Its because of the constant char arrays at the beginning and end 它是因为开头和结尾的常量字符数组

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

The concatenation operator thought VAL_TAG_OPN and VAL_TAG_CLOSE as not a null terminator string. 连接运算符认为VAL_TAG_OPN和VAL_TAG_CLOSE不是空终止符字符串。 Hence the optimizer just ignored them thinking it as garbage. 因此优化器只是忽略了他们认为它是垃圾。

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

This does solve it. 这确实解决了它。

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

Like fbonnet said, it's an order of evaluation issue. 就像fbonnet所说,这是评估问题的一个顺序。

If that line gets evaluated strictly left to right, then the result of each addition is a std::string object, which has an operator overload for addition and things work as you expect. 如果该行从左到右严格评估,那么每次添加的结果都是一个std :: string对象,它有一个运算符重载以便添加,并且事情按预期工作。

If it doesn't get evaluated left to right, then you wind up adding pointers together and who knows what that will get you. 如果它没有从左到右进行评估,那么你最终会将指针添加到一起,谁知道会给你带来什么。

Avoid this construct and just use the += operator on std::string. 避免使用此构造,只需在std :: string上使用+ =运算符即可。

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

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