![]() |
|
![]() ![]() ![]() |
|
ParaPik |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 132 Регистрация: 8.1.2009 Репутация: нет Всего: нет |
У меня имеются 2 переменные типа BSTR. Инициализирую их следующим образом:
Потом вторая переменная в цикле изменяется так:
Проблема в том, что спустя буквально 2-3 итераций цикла адрес, хранящийся в second, становится равный значению переменной first. Т.е. теперь они указывают на одну и ту же строку, first хранит some_value и second хранит some_value!!! Пожалуйста, помогите разобраться. |
||||
|
|||||
Estranged |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 158 Регистрация: 30.8.2010 Репутация: нет Всего: 3 |
Да ладно, чудес не бывает. Код цикла приложите.
|
|||
|
||||
ParaPik |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 132 Регистрация: 8.1.2009 Репутация: нет Всего: нет |
Так, в том то и дело, что это и есть код цикла. Но если в более подробном варианте:
Т.е. изменение переменной second происходит только в конце цикла. Нигде она больше не изменяется. |
|||
|
||||
Estranged |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 158 Регистрация: 30.8.2010 Репутация: нет Всего: 3 |
Просто, как копейка. Как вариант, может быть переполнение буфера где-то или чтение за границей буфера. Приложите весь код функции. Да не может такого быть, чтобы first совпал с новым SysAllocString. Потому что это слишком не правдоподобно.
|
|||
|
||||
ParaPik |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 132 Регистрация: 8.1.2009 Репутация: нет Всего: нет |
Я тоже удивился. Функцию полностью показывать нет смысла. В приложении один поток. Проверял работу кода отладчиком. Именно после очередного вызова SysAllocString происходит приравнивание адресов.
|
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 1 Всего: 250 |
да и вопрос на форуме задавать смысла нет, тут телепатов нет.. |
|||
|
||||
ParaPik |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 132 Регистрация: 8.1.2009 Репутация: нет Всего: нет |
Вот:
Это сообщение отредактировал(а) ParaPik - 2.10.2011, 10:10 |
|||
|
||||
Estranged |
|
||||||
Бывалый ![]() Профиль Группа: Участник Сообщений: 158 Регистрация: 30.8.2010 Репутация: нет Всего: 3 |
А где здесь first?
Я бы заменил
на
Зачем грызть всю строку... Зачем тут _T? Ведь wstring t_result.
|
||||||
|
|||||||
ParaPik |
|
||||||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 132 Регистрация: 8.1.2009 Репутация: нет Всего: нет |
По поводу _T. Я просто убрал из примера препроцессорные директивы, в которых проверяется _UNICODE. По поводу strlen согласен. Что-то я поспешил... Простите, что забыл описать макрос START_PERROR. Он вызывает следующую функцию:
m_error - это и есть first. Я уже пробовал оберткой _bstr_t воспользоваться. Думал, мало ли я что-то не так делаю. Результата ноль. |
||||||||||
|
|||||||||||
Estranged |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 158 Регистрация: 30.8.2010 Репутация: нет Всего: 3 |
Т.е. в цикле вызывается функция Func? m_error инициализировано в "". А что хранится в m_error в тот момент, когда проходит ошибка (m_result = SysAllocString(t_result.c_str()); //Вот здесь ошибка) и что за строка должна быть, т.е. чему равен t_result. Правильно ли я понимаю, что SysAllocString принимает одну строку t_result, а выдает что-то постороннее, или все же возвращает нужное, но и в этот же момент m_error тоже изменяется на это some_value? Т.е. опишите подробнее состояние всех переменных до ошибки и в момент после вызова SysAllocString, когда уже все плохо. |
|||
|
||||
ParaPik |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 132 Регистрация: 8.1.2009 Репутация: нет Всего: нет |
Да, в цикле вызывается Func. При первом вызове функции m_error указывает на "". После первой итерации m_result принимает правильное значение, m_error свое значение не изменяет. То же самое и во второй итерации. Но на третьей итерации SysAllocString возвращает адрес, который содержится в m_error. Этот адрес присваевается m_result. Т.е. теперь обе переменные указывают на одну и ту же строку, строку, верную для m_result. То же самое происходит, даже если m_error указывает на строку не нулевой длины.
|
|||
|
||||
Estranged |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 158 Регистрация: 30.8.2010 Репутация: нет Всего: 3 |
А на третьей итерации в SysAllocString что подается, чему равно t_result? Какая строка? И как я понял, m_error на третьей итерации все еще не меняет свое значение, т.е. равен "". Иными словами должно получаться, что в m_result теперь тоже лежит "" и это верно. Так? Т.е. и m_result, и m_error равны "". Я правильно понимаю?
|
|||
|
||||
ParaPik |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 132 Регистрация: 8.1.2009 Репутация: нет Всего: нет |
t_result практически всегда не нулевая строка. И на третьей итерации она тоже не нулевая. Значение m_error не меняется, а SysAllocString на третьей итерации возвращает значение, содержащиеся в m_error, т.е. ячейка памяти, на которую указывает m_error перезаписывается на содержимое t_result.
Еще я заметил, что такое происходит только тогда, когда при первой инициализации m_result SysAllocString передать пустую строку. Я не знаю, может, это проявилось бы при больших итерациях и при начальной инициализации m_result не пустой строкой. Но самый явный баг в первом случае. |
|||
|
||||
Estranged |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 158 Регистрация: 30.8.2010 Репутация: нет Всего: 3 |
Теперь понятно. Такая багофича есть. А для m_error SysFreeString не вызывается где-нибудь скрыто и незаметно без парного SysAllocString до вызова m_result = SysAllocString(t_result.c_str())? Потому что после SysFreeString строка не уничтожается, а висит в памяти до ближайшего вызова SysAllocString, отчего два указателя указывают на одну память, но уже с другими данными, и один из указателей невалидный.
Убедитесь сами:
Если SysFreeString снести вниз за второй SysAllocString, то и bs, и bs2 хранят свои строки. Отчего я думаю, у Вас есть SysFreeString для m_error без пары SysAllocString, отчего система думает, что строка некогда лежавшая в m_error свободна, отчего использует этот регион памяти повторно, и как бы кажется, что m_error как бы принимает значение t_result, хотя в действительности m_error хранит уже некорректный адрес. Вот как-то так... |
|||
|
||||
ParaPik |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 132 Регистрация: 8.1.2009 Репутация: нет Всего: нет |
SysAllocString и SysFreeString вызывались только парами. Скрыто ничто не может изменить значение. Я уже все заменил на _bstr_t. С этой оберткой вопрос о неправильном освобождении памяти точно отпадает(ничего из-за этого не изменилось). Но я все-таки решил эту проблему. Я теперь просто инициализирую m_error не "", а nullptr. Все равно мне нужно будет получить лишь одну строку: либо m_error, либо m_result. Больше я не вижу решений.
В любом случае, спасибо, Estranged, за участие в решении моей проблемы. |
|||
|
||||
![]() ![]() ![]() |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |