运行时依赖于std :: string连接

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

否则在我已经定义的代码中

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

sVal是一个从string指针数组中检索出来的variables。 这在大部分的系统,windows和linux都可以正常工作。 然而,在一个客户站点,我相信有一个我们已经做了一些广泛的testing的Linux版本,产生一个结果,就好像我从来没有使用过VAL_TAG_OPENVAL_TAG_CLOSE 。 我收到的结果是

 sAttr = sAttr+sVal->c_str(); 

这是怎么回事 ?。 std :: string的连接在运行时是否有所不同?

为什么->c_str() ? 如果sVal是一个std::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似乎是空字符串。

我想你已经有某种缓冲区溢出或无效的指针算术的地方,以便您的程序覆盖包含这些“常量”值的内存。 无论你的内存何时结束,运行时(以及操作系统版本)都是特定的。 过去我一直被类似的东西困扰,通过切换编译器或优化器选项。

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

我不是那个造成问题的评估顺序。 这是因为在开始和结束的时候都是不断的char数组

 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上使用+ =运算符。