1
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_OPENand VAL_TAG_CLOSE. 我收到的结果是

sAttr = sAttr+sVal->c_str();

这是怎么回事 ?。std::string 连接是否随运行时变化?

4

4 回答 4

2

为什么->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;

(无论如何应该更快)。

于 2009-02-12T10:59:33.887 回答
1

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

我猜你在某处有某种缓冲区溢出或无效指针算术,所以你的程序会覆盖包含那些“常量”值的内存。无论您的内存最终在哪里,都确实是运行时(以及操作系统版本)特定的。过去,我通过切换编译器或优化器选项被类似的事情困住了。

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

于 2009-02-12T11:27:40.980 回答
1

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

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);

这确实解决了它。

于 2009-02-16T20:29:31.397 回答
0
sAttr = sAttr+VAL_TAG_OPEN+sVal->c_str()+VAL_TAG_CLOSE;

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

如果该行被严格地从左到右评估,那么每次加法的结果是一个 std::string 对象,它有一个用于加法的运算符重载,并且事情会按您期望的那样工作。

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

避免这种结构,只需在 std::string 上使用 += 运算符。

于 2009-02-12T14:51:58.007 回答