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

Тема в разделе "MS Visual C++", создана пользователем Serjio, 26 апр 2007.

Статус темы:
Закрыта.
  1. Serjio

    Serjio Гость

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

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

    struct S2
    {
    [ др. поля.]
    S1 m_S1;
    [ др. поля]
    }
    есть такая функция:

    Код (Text):
    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
     
  2. European

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    А выравнивание структур какое, если оно есть?

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

    Serjio Гость

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

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

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    <!--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]
    Вот как раз и должно

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

    Serjio Гость

    Нет, этим я не пользовался...

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

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

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    А что возвращает int *p = S2->m_S1.pi ДО вызова функции?
     
  7. Serjio

    Serjio Гость

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

    Serjio Гость

    тоже самое, что и в самой ф-ции func, значение памяти после указанного поля структуры...(вставил эту строчку в main и проверил...)
     
  9. grigsoft

    grigsoft Well-Known Member

    Регистрация:
    15 ноя 2005
    Сообщения:
    735
    Симпатии:
    0
    Поток в программе один?
    Я бы поставил точку останова на изменение памяти по адресу p.
    И изучил асм код сгенеренный.
    А в релизе есть такая проблема?


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

    Serjio Гость

    Поток один.

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

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

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

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

    Serjio Гость

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

    struct S1
    {
    S0 m_S0;
    int* pi;
    }
    Соответственно получалось, что в некоторых проектах __DEBUG__ была определена, а в некоторых - нет, поэтому и смещения поля pi в структуре S1 были разные в разных проектах.

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

    grigsoft Well-Known Member

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

    хе-хе.
     
  14. European

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    <!--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
     
  15. Serjio

    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]
    Да кто ж знал что в этой всей структуре важно а что нет...всю структуру данных воспроизвести нереально было...
     
Загрузка...
Статус темы:
Закрыта.

Поделиться этой страницей