Неверный адрес поля структуры

  • Автор темы Serjio
  • Дата начала
Статус
Закрыто для дальнейших ответов.
S

Serjio

Впервые столкнулся с очень странной ошибкой: при попытке чтения значения поля структуры, считывается значение из памяти соседней по отношению к нужному полю. Код примерно такой (сильно упрощенный вариант, потому что код не могу цитировать):

Код:
struct S1
{
[ др. поля.]
int *pi;
[ др. поля]
}

struct S2
{
[ др. поля.]
S1 m_S1;
[ др. поля]
}

есть такая функция:

Код:
void func(S2 *pS2)
{
int *p = pS2->m_S1.pi;
}

При выполнении функции func (после корректной инициализации - в pi записан адрес выделенной памяти, и аргумент функции тоже правильный) значение переменной р становится равным значению, хранящимся в памяти, следующей сразу после поля pi, т.е. например если поля pi хранится по адресу addr, то в переменную p записывается значение int из памяти addr+4. Причем наблюдаемая ошибка происходит далеко не во всех функциях наподобие func, т.е. к некоторых все считывается верно.

Все это происходит в солюшене под VS7.1, в солюшене 6 проектов, причем структуры S1 и S2 описаны в разных проектах, вызов функции func производится из третьего проекта (не знаю важно это или нет).
Не проверял точно ли это, но заметил, что в функциях из проекта, где описана S2, считавание происходит верно, в других - неверно, но повторюсь, конкретно во всех функциях солюшена не проверял, так что это не точно...

Есть подозрение что проблема связана с настройками проектов (конфигурации), именно поэтому решил поместить данный вопрос в этот раздел. Но сколько я не менял настройки, ничего не помогало...

Забыл сказать, все это реализовано с чистом С (все проекты один сплошной С).

Буду очень благодарен, если подскажете в чем дело! Потратил уже достаточно много рабочего времени и не смог справиться с этой проблемой...могу даже пиво поставить! :D
 
E

European

А выравнивание структур какое, если оно есть?

Упаковку полей структуры используешь?
 
S

Serjio

А выравнивание структур какое, если оно есть?

Упаковку полей структуры используешь?

Если выравнивание структур задается в Configuration Properties -> C/C++ -> Code Generation -> Struct Member Alignment, то значение этого параметра равно Default для всех проектов. Хотя я пробовал менять его и на другие значения - не помогло. Но ведь это и не должно влиять в описанном случае?!

А где в VS задается эта упаковка полей структуры?
 
E

European

<!--QuoteBegin-Serjio+26:04:2007, 13:36 -->
<span class="vbquote">(Serjio @ 26:04:2007, 13:36 )</span><!--QuoteEBegin-->А где в VS задается эта упаковка полей структуры?
[snapback]63583" rel="nofollow" target="_blank[/snapback]​
[/quote]
Она при объявлении структуры указывается: после объявления поля ставится : после которой размер в битах

<!--QuoteBegin-Serjio+26:04:2007, 13:15 -->
<span class="vbquote">(Serjio @ 26:04:2007, 13:15 )</span><!--QuoteEBegin-->Причем наблюдаемая ошибка происходит далеко не во всех функциях наподобие func, т.е. к некоторых все считывается верно.
[snapback]63575" rel="nofollow" target="_blank[/snapback]​
[/quote]
А ты уверен, что нигде значение указателя не изменяется?

<!--QuoteBegin-Serjio+26:04:2007, 13:36 -->
<span class="vbquote">(Serjio @ 26:04:2007, 13:36 )</span><!--QuoteEBegin-->Но ведь это и не должно влиять в описанном случае?!
[snapback]63583" rel="nofollow" target="_blank[/snapback]​
[/quote]
Вот как раз и должно

Если ты менял значение, то советую после этого пересобрать проект полностью
 
S

Serjio

Она при объявлении структуры указывается: после объявления поля ставится : после которой размер в битах
Нет, этим я не пользовался...

А ты уверен, что нигде значение указателя не изменяется?
уверен, в дебаге посмотрел что лежит в соседней памяти на момент выполнения строки с неправильным присваиванием (в ф-ции func)...

Вот как раз и должно
Я имел в виду, что даже если выравнивание и задано, то не должно все работать как описано, да и не менял я выравнивание до появления этой ошибки, а потом после изменения все пересобирал..
 
E

European

А что возвращает int *p = S2->m_S1.pi ДО вызова функции?
 
S

Serjio

Добавлю еще вот что, когда в дебаге останавливаешься после выполнения строчки из ф-ции func, то значение переменной pi равно правильному адресу, а вот значение переменной p этому правильному ажресу не равно, т.е. сразу после выполнения присваивания значения переменных - разные ! я вообще не понимаю как такое возможно... :D
 
G

grigsoft

Поток в программе один?
Я бы поставил точку останова на изменение памяти по адресу p.
И изучил асм код сгенеренный.
А в релизе есть такая проблема?


Да, #pragma pack нигде не используется?
И что если вставить сравнение после присваивания?
Код:
if (p == S2->m_S1.pi)...
 
S

Serjio

Поток в программе один?
Я бы поставил точку останова на изменение памяти по адресу p.
И изучил асм код сгенеренный.
А в релизе есть такая проблема?
Да, #pragma pack нигде не используется?
И что если вставить сравнение после присваивания?
Код:
if (p == S2->m_S1.pi)...

Поток один.

АСМ код изучил, там в переменную p записывается значения памяти по адресу с неверным смещением относительно начала структуры...т.е. сам адрес вычисляется неверно..

прагма паков нету

сравнение возвращает true (а дебаггер показывает разные значения)
 
E

European

Для: Serjio
У меня похожие проблемы были с проектами под Pocket PC в VS 2005 (отладчик показывает одно значение, а на самом деле оно другок), я их так и не решил. Обходился отладочными макросами. Чем тебе помочь, у меня даже и идей нет
 
S

Serjio

Решил проблему! Дело было вот в чем: структура данных была такая:
Код:
struct S0
{
[др. поля]
#ifdef __DEBUG__
int *debug;
#endif
}

struct S1
{
S0 m_S0;
int* pi;
}

Соответственно получалось, что в некоторых проектах __DEBUG__ была определена, а в некоторых - нет, поэтому и смещения поля pi в структуре S1 были разные в разных проектах.

Всем спасибо! Ваши советы помогли!
 
G

grigsoft

Оптимизация отключена в дебаге? Вообще проблема только в том что отладчик неверно показывает, или реально в проекте неправильно работает? В первом случае я бы забил - бывает такое. Во втором - непонятно. Особенно при отсутствии оптимизации. Я раз встречался в релизе с подобной проблемой, которая решилась только отключением оптимизации для конкретной функции через прагму. Т.е. в чистом виде ошибка компилятора. Но чтобы в дебаге? Я больше склонен грешить на различное выравнивание в модулях. Попробуй в разных функциях (где работает это, и где нет) вызвать sizeof(S1) и S2. Будут одинаковые результаты?

хе-хе.
 
E

European

<!--QuoteBegin-Serjio+26:04:2007, 13:15 -->
<span class="vbquote">(Serjio @ 26:04:2007, 13:15 )</span><!--QuoteEBegin-->Код примерно такой (сильно упрощенный вариант, потому что код не могу цитировать)
[snapback]63575" rel="nofollow" target="_blank[/snapback]​
[/quote]
Вот не надо было так упрощать :D
 
S

Serjio

<!--QuoteBegin-European+27:04:2007, 16:23 -->
<span class="vbquote">(European @ 27:04:2007, 16:23 )</span><!--QuoteEBegin-->Вот не надо было так упрощать smile.gif
[snapback]63764" rel="nofollow" target="_blank[/snapback]​
[/quote]
Да кто ж знал что в этой всей структуре важно а что нет...всю структуру данных воспроизвести нереально было...
 
Статус
Закрыто для дальнейших ответов.
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!