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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблема со статической переменной 
:(
    Опции темы
Xuch
Дата 23.12.2013, 18:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Друзья, выручайте!
Что-то я в тупике очередном.

Ситуация такая: есть функция статическая, которая вызывается по определенному событию. В функцию передается указатель gpointer на класс, содержащий переменную, и в этой функции переменная этого класса устанавливается в "1".

Далее мне необходимо уже из не-статического метода этого класса узнать значение этой переменной. Я все время ее вижу как "0", хотя при следующем вызове статической функции она видит эту переменную правильно как "1".

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

Спасибо! 
PM MAIL   Вверх
feodorv
Дата 23.12.2013, 18:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



Цитата(Xuch @  23.12.2013,  19:53 Найти цитируемый пост)
Я все время ее вижу как "0", хотя при следующем вызове статической функции она видит эту переменную правильно как "1".

А у Вас и там и там одинаковые экземпляры класса?
gpointer - это void *, да? В коде правильное приведение типов?


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Xuch
Дата 23.12.2013, 19:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Экземпляры одни и те же.. приведение типа правильное.
Остальные члены (не-статические) прекрасно отображаются как в статической функции, так и в не-статической.
PM MAIL   Вверх
baldina
Дата 23.12.2013, 19:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



PM MAIL   Вверх
Xuch
Дата 23.12.2013, 19:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



baldina, огромное спасибо!
PM MAIL   Вверх
Xuch
Дата 23.12.2013, 21:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Все равно не работает...
Опишу подробнее.

enum RState
{
  NOTINITIALIZED = 0,
  INITIALIZED,
  STOPPED,
  WRITING
};

class CType
{
  public:
  RState State[2];
  static void SetRState(gpointer, size_t, RState);
  static gboolean BusCall(GstBus *, GstMessage *, gpointer);
}

CType::CType
{
  State[0] = NOTINITIALIZED;
  State[1] = NOTINITIALIZED;
}

void CType::SetState(gpointer ptr, size_t i, RState rstate)
{
  CType *Cm = (CType *) ptr;

  if ((i <= 1) && (i >= 0))
    {
      Cm->RState[0] = rstate;
    }
}

gboolean CType::BusCall(GstBus *bus, GstMessage *msg, gpointer data)
{
  CType *Cm = (CType *) data;
  printf("DEBUG: State[0] = %d\n", State[0]);
  if (State[0] == NOTINITIALIZED)
     SetState(Cm, 0, WRITING);
  printf("DEBUG: State[0] = %d\n", State[0]);   --> Здесь правильно выводит статус WRITING
}

void CType::PrintState(size_t i)
{
    printf("DEBUG: State[%d] = %d\n", i, State[i]);
}

Если после вызова функции BusCall вызвать функцию PrintState(0), то она всегда будет выдавать значение "0", соответствующее NOTINITIALIZED.
При следующем вызове BusCall правильно отобразит ранее измененный статус WRITING, однако какие бы изменения не вносились функцией BusCall, при вызове функции PrintState(0) все равно всегда 0.

Честно говоря уже сломал всю голову...
PM MAIL   Вверх
baldina
Дата 23.12.2013, 21:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



это все страшно интересно, но хотелось бы увидеть как эти функции вызываются
PM MAIL   Вверх
Xuch
Дата 23.12.2013, 21:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



void CType::Init()
{
   gst_bus_add_watch(Bus2, BusCall, this);
}

Тут BusCall это статическая функция, описанная выше, а this указатель на класс CType

PM MAIL   Вверх
baldina
Дата 23.12.2013, 22:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Xuch, покуда вы будете приводить не ваш код, а только огрызки (к тому же с синтаксическими ошибками), помочь вам будет нельзя. Кстати, пользуйтесь кнопочкой "код".
Из того, что привели удалось слепить вот что http://ideone.com/yJ74C0
и оно работает как и ожидалось.
Есть подозрение, что ошибка где-то в другом месте, но вы его скрываете от нас))

Добавлено через 2 минуты и 14 секунд
кстати забавная у вас функция 
Код

void CType::SetRState(gpointer ptr, size_t i, RState rstate)
{
  CType *Cm = (CType *) ptr;

  if ((i <= 1) && (i >= 0))
    {
      Cm->State[0] = rstate;
    }
}

она устанавливает State[0] независимо от параметра i
PM MAIL   Вверх
baldina
Дата 23.12.2013, 22:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



кстати, почему есть SetRState, но нет GetRState? Зачем SetRState статическая? зачем State public?
я бы переделал хотя бы так:
Код

class CType
{
  RState State[2];

  public:

  CType () : State{NOTINITIALIZED,NOTINITIALIZED} {
    Init();
  }

  void Init() {
        ...
        gst_bus_add_watch (Bus2, BusCall, this);
  }

  void SetRState (size_t i, RState rstate) {
    if (i <= sizeof(State)/sizeof(State[0]))
      State[i] = rstate;
  }

  RState GetRState (size_t i) const {
    if (i <= sizeof(State)/sizeof(State[0]))
      return State[i];
    else
      throw std::range_error ("State index must be 0 or 1");
  }

  void PrintState(size_t i) const {
    cout << "DEBUG: State[" << i << "] = " << State[i] << endl;
  }

  static void BusCall(GstBus *, GstMessage *, gpointer data) {
    ...
    CType *Cm = reinterpret_cast<CType*>(data);
    if (Cm->GetRState (0) == NOTINITIALIZED)
      Cm->SetRState (0, WRITING);
  }
};


Это сообщение отредактировал(а) baldina - 23.12.2013, 22:43
PM MAIL   Вверх
Xuch
Дата 24.12.2013, 06:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Я не могу привести весь код, там несколько тыс строк..
Точнее я конечно могу, но думаю будет трудно читабельно

Код

Cm->State[0] = rstate;

тут ошибся когда набирал, конечно должно быть
Код

Cm->State[i] = rstate;




Это сообщение отредактировал(а) Xuch - 24.12.2013, 06:23
PM MAIL   Вверх
feodorv
Дата 24.12.2013, 06:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



Цитата(Xuch @  23.12.2013,  22:23 Найти цитируемый пост)
  static void SetRState(gpointer, size_t, RState);

Цитата(Xuch @  23.12.2013,  22:23 Найти цитируемый пост)
void CType::SetState(gpointer ptr, size_t i, RState rstate)

Тут Вы тоже ошиблись, когда набирали?

Добавлено через 5 минут и 19 секунд
Вместе со значением State[0] выводите ещё значение data/this.


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Xuch
Дата 24.12.2013, 16:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



baldina, не работает этот вариант.. Все по-прежнему...
Такое ощущение, что эта переменная в функции BusCall имеет один адрес в памяти, а во всех остальных функциях - другой. Как бы значения этой переменной не менялись, видит их корректно только BusCall, все остальное читает всегда "0".

Мыслей больше нет...
PM MAIL   Вверх
Xuch
Дата 24.12.2013, 17:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Не дает исходники разместить... пишет макс длина 30000 символов
PM MAIL   Вверх
baldina
Дата 24.12.2013, 17:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Xuch @  24.12.2013,  17:05 Найти цитируемый пост)
Не дает исходники разместить

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

Добавлено через 29 секунд
Цитата(Xuch @  24.12.2013,  16:27 Найти цитируемый пост)
Такое ощущение, что эта переменная в функции BusCall имеет один адрес в памяти, а во всех остальных функциях - другой

это легко выяснить отладочной печатью или в отладчике

Добавлено через 2 минуты и 7 секунд
кстати, раздельная компиляция иногда дает неожиданные ошибки. например, если есть копии заголовочного файла, и они отличаются, могут отличаться размеры структур и классов, это ведет к непредсказуемому поведению.
PM MAIL   Вверх
Xuch
Дата 24.12.2013, 17:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



baldina, написал вам на почту..
Дело в том, что PrintState вызывается по соответствующей команде с Tcp-сервера, в который передается указатель на другой экземпляр класса, который содержит уже экземпляр рассматриваемого класса...может тут я что-то намудрил с указателями. С отладкой сложно, т.к. целевая машина это ARM с ограниченными ресурсами и gdb сервер там пока установить не получается.

Добавлено через 3 минуты и 19 секунд
Что-то не работает Ваша почта.. пишет ящик не существует.
PM MAIL   Вверх
feodorv
Дата 24.12.2013, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



Цитата(Xuch @  24.12.2013,  18:35 Найти цитируемый пост)
может тут я что-то намудрил с указателями

Цитата(feodorv @  24.12.2013,  07:46 Найти цитируемый пост)
Вместе со значением State[0] выводите ещё значение data/this

Ну, проверьте, несложно же...


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Xuch
Дата 24.12.2013, 21:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Проверил - адреса указателей все правильные и одинаковые.
Мистика...
PM MAIL   Вверх
feodorv
Дата 25.12.2013, 07:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



Цитата(Xuch @  24.12.2013,  22:59 Найти цитируемый пост)
Мистика...

Ну почему, есть ещё варианты)))
Цитата(baldina @  24.12.2013,  18:24 Найти цитируемый пост)
кстати, раздельная компиляция иногда дает неожиданные ошибки. например, если есть копии заголовочного файла, и они отличаются, могут отличаться размеры структур и классов, это ведет к непредсказуемому поведению. 

Перекомпилите всё с нуля. Быть может, Вы вносили изменения в классы, неперекомпилив исходники, которые с этими классами работают. Тогда поле State может располагаться по разным смещениям относительно данных класса в разных частях программы...

Добавлено через 5 минут и 57 секунд
То есть теперь вместо data/this выдайте на печать адрес State[0]. Если адреса State[0] в функциях BusCall и PrintState совпадают, то тогда придётся признать, что где-то между этими вызовами Вы затёрли память State в ноль. Нужно будет просто найти это место...


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Xuch
Дата 25.12.2013, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



С нуля уже много раз компилил.. копий заголовочных файлов нет.
Память не затирается, т.к. позже при вызове BusCall значение переменной State читается правильно. Единственная мысль на данный момент - что адрес переменной State в функциях самого класса отличается.. как такое может быть не понимаю, факт есть факт - ЧАСТЬ переменных читается КОРРЕКТНО, а ДРУГАЯ ЧАСТЬ - неинициализированными значениями.
PM MAIL   Вверх
Xuch
Дата 31.12.2013, 14:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Всем большое спасибо за участие!
Проблема решена, проблема была не в указателях, а в GMainLoop - часть функций работала внутри GMainLoop и меняла переменные, а другая функция запускалась как отдельный процесс через fork(), которая читала по этому же адресу в памяти другие значения. Как только убрал fork() и поместил все в GMainLoop, все заработало.

Правда возникла другая проблема, но это уже в другой теме.
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


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

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


 




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


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

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