Зависимость времени выполнения для конкатенации std :: string - PullRequest
1 голос
/ 12 февраля 2009
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_OPEN и VAL_TAG_CLOSE. Я получаю результаты для

sAttr = sAttr+sVal->c_str();

Что происходит? Меняется ли конкатенация std :: string во время выполнения?

Ответы [ 4 ]

2 голосов
/ 12 февраля 2009

Почему ->c_str()? Если sVal является std::string, попробуйте удалить этот вызов. Помните, что порядок вычисления не определен, поэтому вы можете добавить указатели вместо конкатенации строк, потому что VAL_TAG_OPEN, sVal->c_str() и VAL_TAG_CLOSE - все простые строки Си Я предлагаю вам использовать оператор присваивания сложения +=, например, :

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

(что в любом случае должно быть быстрее).

1 голос
/ 16 февраля 2009

Я не думаю, что порядок оценки вызывает проблему. Это из-за постоянных массивов символов в начале и конце

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

Это решает проблему.

1 голос
/ 12 февраля 2009

Нет, объединение std :: string определенно не должно зависеть от времени выполнения, но почему-то VAL_TAG_OPEN и VAL_TAG_CLOSE кажутся пустыми строками.

Я бы предположил, что у вас где-то есть переполнение буфера или неверная арифметика указателей, так что ваша программа перезаписывает память, содержащую эти "постоянные" значения. Везде, где заканчивается ваша память, она действительно зависит от времени выполнения (и, следовательно, от версии ОС). Я был пойман в ловушку подобных вещей в прошлом, переключая компиляторы или опции оптимизатора.

Как вы упомянули, сохраняя необработанные указатели на экземпляры std :: string в необработанных массивах, такие ошибки на самом деле не всегда невероятны, но их может быть трудно обнаружить, так как использование сборки DEBUG не даст вам никаких итерационных проверок со всеми все это в СЫРЬЕ ... Удачи.

0 голосов
/ 12 февраля 2009
sAttr = sAttr+VAL_TAG_OPEN+sVal->c_str()+VAL_TAG_CLOSE;

Как сказал fbonnet, это вопрос порядка оценки.

Если эта строка вычисляется строго слева направо, то результатом каждого добавления является объект std :: string, который имеет перегрузку оператора для добавления, и все работает так, как вы ожидаете.

Если он не оценивается слева направо, вы добавляете указатели вместе, и кто знает, что это даст вам.

Избегайте этой конструкции и просто используйте оператор + = в std :: string.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...