Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Порча закрытых переменных класса

22K
27 декабря 2007 года
deninok
16 / / 01.03.2007
Уважаемые участники форума!

Возник у меня интересный и важный вопрос:
что может явится причиной порчи значения закрытой переменной класса?
Допустим, у меня есть класс:

class Timer {
public:
Timer(int flag) : m_flag(flag) {}
~Timer() {}
private:
int m_flag;
//...
};


Я использую переменную m_flag только внутри класса, причем использование сводится к:
- явному присваиванию ей значения 1
- явному присваиванию ей значения 0
- сравнению ее с 1 и/или 0.
В общем, реализован простой логический флаг. Сразу скажу: по причине вынужденного использования старого компилятора, не поддерживающего стандартный С++, я, к сожалению, НЕ могу использовать для переменной m_flag тип bool.
Я создаю несколько объектов класса Timer, образующих двухсвязный линейный список. Разумеется, у каждого из них имеется свой уникальный экземпляр переменной m_flag. Если проверить значение m_flag сразу после создания каждого из этих объектов, то становится видно, что значение m_flag такое, каким и должно быть: 0 или 1 (как и было передано конструктору). Так вот, в процессе работы программы выясняется, что в некоторых из объектов класса Timer значение m_flag вдруг заполняется мусором (каким-то очень большим, положительным или отрицательным, числом). Причем значение переменной m_flag в других объектах класса Timer НЕ портиться, а работает как надо (то есть в любой момент времени содержит в себе 0 или 1).
Вопрос: почему такое может происходить?
Заранее благодарен за помощь.
1.6K
27 декабря 2007 года
Vov4ick
476 / / 01.02.2007
"Вдруг" быть не может. Возможно что неправильно сделана работа с указателями и кто-то пишет не туда, куда надо. Возможно перед проверкой флагу не присваивается значение. Пусть его присваивает либо конструктор, либо прямо при создании объекта.
ЗЫ В стандартном Ц++ типа bool как я помню нет. В любом случае это то же, что и char.
22K
27 декабря 2007 года
deninok
16 / / 01.03.2007
[QUOTE=Vov4ick]"Вдруг" быть не может. [/QUOTE]
Это и я понимаю, однако проблема есть, и ее нужно решать.

[QUOTE=Vov4ick]Возможно что неправильно сделана работа с указателями и кто-то пишет не туда, куда надо. [/QUOTE]
С этой переменной я не работаю посредством указателей. Только явное присваивание 0 или 1, а также сравнение в if-конструкциях.

[QUOTE=Vov4ick]Возможно перед проверкой флагу не присваивается значение. [/QUOTE]
Присваивается.

[QUOTE=Vov4ick]Пусть его присваивает либо конструктор, либо прямо при создании объекта. [/QUOTE]
Так и просходит! В конструкторе явно задается значение этого флага. Причем, как я уже писал выше, если проверить значение этой переменной сразу после окончания тела конструктора, то значение там то, какое нужно.

[QUOTE=Vov4ick]ЗЫ В стандартном Ц++ типа bool как я помню нет. В любом случае это то же, что и char.[/QUOTE]
В стандартном С++ тип bool есть. Может, есть смысл использовать для этого флага тип char?
3
27 декабря 2007 года
Green
4.8K / / 20.01.2000
Ты сам организуешь список или пользуешься стандартным контейнером?
Как уже говорили, проблема может быть в том, что ты разыменовываешь невалидный указатель. Другая причина может быть в том, что ты ошибочно пишешь (опять же из-за невалидного указателя или же из-за выхода за границы массива) в память, где располагается твой объект.
Короче вариантов только два:
1) ты не там читаешь,
2) ты что-то пишешь ошибочно поверх.

В любом случае информации, которую ты предоставил недостаточно, чтоб точно сказать тебе причины.

Возьми отладчик, поставь точку останова на изменение памяти, которая у тебя портиться, и запусти программу. Делов то...
22K
27 декабря 2007 года
deninok
16 / / 01.03.2007
[QUOTE=Green]Ты сам организуешь список или пользуешься стандартным контейнером?[/QUOTE]
Сам организую, поскольку использовать стандартную библиотеку я не могу. К великому сожалению...
Реализую просто: каждый элемент имеет указатель m_next и m_prev, а также имеются статические указатели first и last. Все предельно понятно.

[QUOTE=Green]Короче вариантов только два:
1) ты не там читаешь,
2) ты что-то пишешь ошибочно поверх.[/QUOTE]
Читаю точно там, в этом сомнений нет. Там слишком простая конструкция. А вот то, что ошибочно пишу что-то поверх - это более реально...
В любом случае, благодарю за совет.
22K
27 декабря 2007 года
deninok
16 / / 01.03.2007
На самом деле, в классе Timer имеются несколько закрытых переменных: флаг, порядоковый номер и еще одна переменная. Первые две типа int, а третья - unsigned long int.
Так вот, мусором (в некоторый момент времени) заполняются все три этих переменных! Повторю: такое "замусоривание" происходит только с некоторыми объектами класса Timer в списке. С другими же все абсолютно правильно! Это-то меня и удивляет...
240
27 декабря 2007 года
aks
2.5K / / 14.07.2006
Ну значит действительно портишь память? где расспологается этот объект в другом месте.
22K
28 декабря 2007 года
deninok
16 / / 01.03.2007
Удивительное дело, но заработало! Вернее даже так: заработало несколько странно.
Итак, имеется двухсвязный список объектов класса Timer, в котором (на данный момент) 54 объекта. Созданы они динамически. Так вот, объект, который был 54-м по счету (то есть последним) не работал, поскольку его закрытые переменные как раз и замусоривались (о чем я и говорил выше). И я попробовал перенести его в другое место. То есть, изменив порядок создания объектов, сделал его (например) 9-м. И он заработал! Другое дело, что объект, который теперь стал 54-м, я пока еще не проверял...

Но проблема еще и в том, что закрытые переменные замусоривались НЕ только в 54-м объекте списка, но и в нескольких других (по меньшей мере, в двух или трех). Причем напомню, что другие объекты работают как часы, без малейших сбоев!
5
28 декабря 2007 года
hardcase
4.5K / / 09.08.2005
Цитата: deninok
Удивительное дело, но заработало!


Под какую архитектуру пишем?
Как зовут компилятор?

Может быть у тебя элементарно память сбоит по конкретным адресам.

22K
28 декабря 2007 года
deninok
16 / / 01.03.2007
Пишу под промышленный контроллер с 16-разрядной DOS-подобной операционной системой (MiniOS 7, если интересно). Компилятор - Borland C++ 3.1. Создаю стандартный DOS .exe файл с набором инструкций для 80186.

[QUOTE=hardcase]Может быть у тебя элементарно память сбоит по конкретным адресам.[/QUOTE]
Ну, теоретически такое возможно. Но я надеюсь, что это не так. Хотя...

Я все-таки предполагаю, что проблема в том, что некий код моей программы каким-то образом записывает (нечто) в ту область памяти, где как раз и расположены мои переменные. Вот они и замусориваются. Если я работаю с массивом с помощью указателя, то при выходе указателя за границы массива такое, в принципе, возможно.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог