Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Ошибка при адресации поля структуры 
:(
    Опции темы
Serjio
Дата 26.4.2007, 22:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 26.4.2007

Репутация: нет
Всего: нет



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

Код

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, т.е. к некоторых все считывается верно. В отладчике значения переменных p и pi разные (сразу после выполнения указанной строки функции func), причем значение pS2->m_S1.pi - верное, а р - нет, т.е. получается что сразу после выполнения присваивания значения переменных разные!

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

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

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

Заранее спасибо!

Это сообщение отредактировал(а) Serjio - 26.4.2007, 22:06
PM MAIL   Вверх
archimed7592
Дата 26.4.2007, 22:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



во-первых, есть подозрение, что сами структуры определены не в одном хэдере, а в самом коде, что при несинхронизованном изменении определений будет давать именно такой эффект... либо не в коде, а в просто в нескольких местах (хедерах)...

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

ставлю 90%, что проблема решится в процессе составления псевдокода проявляющего проблему... smile


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
Fazil6
Дата 26.4.2007, 22:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



проверь чтобы у всех проектов было в настройках одинаковое значение в CodeGeneration->Runtime Library и CodeGeneration->Struct Member Alignment
PM MAIL   Вверх
Serjio
  Дата 27.4.2007, 11:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 26.4.2007

Репутация: нет
Всего: нет



Цитата(archimed7592 @  26.4.2007,  22:40 Найти цитируемый пост)
во-первых, есть подозрение, что сами структуры определены не в одном хэдере, а в самом коде, что при несинхронизованном изменении определений будет давать именно такой эффект... либо не в коде, а в просто в нескольких местах (хедерах)...


структуры S1 и S2 действительно описаны в разных хедерах, более того в разных проектах, но разве это криминал? 

Цитата(Fazil6 @  26.4.2007,  22:45 Найти цитируемый пост)
проверь чтобы у всех проектов было в настройках одинаковое значение в CodeGeneration->Runtime Library и CodeGeneration->Struct Member Alignment 

Да, это я уже сделал много раз smile
PM MAIL   Вверх
archimed7592
Дата 27.4.2007, 12:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(Serjio @  27.4.2007,  11:38 Найти цитируемый пост)
но разве это криминал

вот что есть криминал:
Код
// h1.h
struct S1
{
int x;
};
struct S2
{
char c;
S1 s;
double d;
};

// h2.h
struct S1
{
int x;
};
struct S2
{
/* char c; */
S1 s;
double d;
};


// module1.c
#include "h1.h"

/* bla-bla-bla */


// module2.c
#include "h2.h"

/* bla-bla-bla */
структуры вроде одинаковые, но описаны в разных местах... потом гениальный программист по неваедомым нам причинам закоментил char c - всё, структуры стали разными... они должны быть определены только в одном месте (ты можешь сделать по хедеру на структуру, но конкретная структура должна быть определена только в одном хэдере)


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
Serjio
Дата 27.4.2007, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 26.4.2007

Репутация: нет
Всего: нет



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

struct S1
{
  S0 m_S0;
  int* pi;
}


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

Всем спасибо! Ваши советы помогли!
PM MAIL   Вверх
Daevaorn
Дата 27.4.2007, 16:51 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(Serjio @  27.4.2007,  15:53 Найти цитируемый пост)
Решил проблему! Дело было вот в чем: структура данных была такая:

нет слов просто...
PM MAIL WWW   Вверх
JackYF
Дата 27.4.2007, 20:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(Serjio @  27.4.2007,  14:53 Найти цитируемый пост)
[др. поля]
#ifdef __DEBUG__
int *debug;
#endif


Да, полностью согласен с Daevaorn, такого еще не видал...


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Serjio
Дата 28.4.2007, 09:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 26.4.2007

Репутация: нет
Всего: нет



Цитата(JackYF @  27.4.2007,  20:32 Найти цитируемый пост)
Да, полностью согласен с Daevaorn, такого еще не видал... 

Как по хорошему сделать то же самое? Нужно включать и отключать часть кода по быстрому...ИМХО это был самый простой способ...
PM MAIL   Вверх
JackYF
Дата 28.4.2007, 13:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(Serjio @  28.4.2007,  09:15 Найти цитируемый пост)
Как по хорошему сделать то же самое? Нужно включать и отключать часть кода по быстрому


Код

#ifdef DEBUG
... тут код для дебага
#endif


Это - в кодaх функций, ни в коем случае не в описании структур, классов и т.д.
Поля структуры данных должны быть определены однозначно.

А вот в коде ты можешь эти заглушки ставить столько, сколько тебе нужно.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Daevaorn
Дата 28.4.2007, 14:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(Serjio @  28.4.2007,  10:15 Найти цитируемый пост)
Как по хорошему сделать то же самое? Нужно включать и отключать часть кода по быстрому...ИМХО это был самый простой способ...

А как по твоему надо вопросы задавать? Сразу про этот твой "простой способ" сказать было нельзя?smile
PM MAIL WWW   Вверх
Serjio
Дата 28.4.2007, 14:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 26.4.2007

Репутация: нет
Всего: нет



Цитата(JackYF @  28.4.2007,  13:55 Найти цитируемый пост)
Это - в кодaх функций, ни в коем случае не в описании структур, классов и т.д.
Поля структуры данных должны быть определены однозначно.

А вот в коде ты можешь эти заглушки ставить столько, сколько тебе нужно.


Логично, спасибо! Но минус данного способа в том, что тогда не получится автоматом "чистить" код. Суть в том что иногда надо быстро весь код окруженный #ifdef _DEBUG удалить, и я для этого юзал спец-ый скрипт. А в предложенном методе прийдется структуры чистить вручную...



Цитата(Daevaorn @  28.4.2007,  14:10 Найти цитируемый пост)
А как по твоему надо вопросы задавать? Сразу про этот твой "простой способ" сказать было нельзя?smile


Дык, если бы я про него помнил, то и вопроса не было... тут дело в том, что все, что я тут написал, далеко не на виду в исходном коде, в том коде что у меня это все увидеть стоило больших трудов...собственно именно поэтому сразу не понимал в чем дело...
PM MAIL   Вверх
Ken
Дата 28.4.2007, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 31.3.2007

Репутация: 2
Всего: 4



Нет проблем в том что и в .h файлах тоже условные компиляции которые могут менять длину структур в зависимости от переменных препроцессора. Это тоже не криминал. Просто надо перекомпилить все модули которые используют эти структуры при их изменениях. Если все это в составе одного проекта то корректно составленный мейк-файл делает все.
PM MAIL   Вверх
JackYF
Дата 28.4.2007, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(Ken @  28.4.2007,  15:06 Найти цитируемый пост)
Нет проблем в том что и в .h файлах тоже условные компиляции которые могут менять длину структур в зависимости от переменных препроцессора. Это тоже не криминал. Просто надо перекомпилить все модули которые используют эти структуры при их изменениях. Если все это в составе одного проекта то корректно составленный мейк-файл делает все. 


А немного некорректно составленный мэйк-файл может настолько испортить всю эту малину.
У меня еще раз вопрос - зачем?

Цитата(Ken @  28.4.2007,  15:06 Найти цитируемый пост)
Если все это в составе одного проекта

а если не одного? У меня некоторые структуры моих данных используются в десятках проектов...

Так... теперь дальше...

Цитата(Serjio @  28.4.2007,  14:37 Найти цитируемый пост)
Суть в том что иногда надо быстро весь код окруженный #ifdef _DEBUG

Нескромный вопрос - зачем? Для релизного кода достаточно не определять _DEBUG, это понятно...

Но если уже так надо, то...

Цитата(Serjio @  28.4.2007,  14:37 Найти цитируемый пост)
и я для этого юзал спец-ый скрипт

Неужели сложно этот скрипт переделать или написать свой?

Добавлено через 2 минуты и 27 секунд
Цитата(Ken @  28.4.2007,  15:06 Найти цитируемый пост)
Это тоже не криминал.

имхо, это плохой стиль и чреватый потенциальными граблями.

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

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



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Ken
Дата 28.4.2007, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 31.3.2007

Репутация: 2
Всего: 4



Когда вы пишете кросс-платформенный код, часто приходится использовать разные типы полей в зависимости от системы. Например, HANDLE в Windows и int в *nix. По соображениям KISS не хочется их абстргировать внутри структуры PrivateData и использовать указатель к этим данным. Кроме того хотите вы это или нет, в активно разрабатываемом проекте все равно часто приходится менять .h файлы вне зависимости от того как вы их составляете и вы ОБЯЗАНЫ пересобрать все модули (как только добавляете, удаляете поля или меняете их тип). Так что ваш хороший стиль все равно не избавляет от корректных мейк-файлов или от корректных компиляций.

Это сообщение отредактировал(а) Ken - 28.4.2007, 17:27
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0994 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.