Я встретил очень странное поведение с закрытой переменной в классе.
Описание проблемы: значение закрытого члена «current» в классе lapi_xmeef_table ненормально изменяется в конце функции-члена.
класс 1: lapi_xmeef
класс 2: lapi_xmeef_table (является другом lapi_xmeef, поэтому может получить доступ к закрытым переменным в lapi_xmeef напрямую или через публичные интерфейсы)
class lapi_xmeef {
friend class lapi_xmeef_table;
...
short bias_frag_layer;
int bias_frag_index;
...
public:
// Add constructor
lapi_xmeef();
// Add public interface
...
void bias_frag(int *li, int *fi);
};
class lapi_xmeef_table {
private:
lapi_xmeef *current;
...
public:
lapi_xmeef_table(Lapi_ctl *ctl, int num_layer);
...
void get_bias(int *li, int *fi);
...
};
Закрытая переменная в lapi_xmeef_table, называемая current, является текущим итератором (класс lapi_xmeef).
Функция-член делает только чтение, она копирует два значения из своих закрытых членов. Показать, как показано ниже
void lapi_xmeef::bias_frag(int *li, int *fi)
{
*li = (short)bias_frag_layer;
*fi = bias_frag_index;
}
Проблемная функция и переменная:
void lapi_xmeef_table::get_bias(int *li, int *fi)
{
// current is (lapi_xmeef *) 0x2a9a93c7f0 (a valid address)
current->bias_frag(li, fi);
// current is (lapi_xmeef *) 0x2a000000df (a invalid address)
}
Перед вызовом функции ток равен (lapi_xmeef *) 0x2a9a93c7f0 (действительный адрес)
После этого текущий (lapi_xmeef *) 0x2a000000df (неверный адрес)
Это происходит не каждый раз, когда вызывается функция-член, до этого странного поведения она вызывается много раз без проблем.
Когда в следующий раз к элементу в текущем обращаются, происходит ошибка сегмента, потому что неверный адрес разыменован.
Теперь мое решение — использовать временный указатель, чтобы сохранить значение current перед вызовом его функции-члена, а затем восстановить его после вызова. Оно работает.
void lapi_xmeef_table::get_bias(int *li, int *fi)
{
lapi_xmeef *temp = current;
current->bias_frag(li, fi);
current = temp;
}
Но я очень хочу знать, почему и как это исправить, а не так хитро.
Почему изменяется значение закрытой переменной, которая, как ожидается, будет такой же?
Есть ли какие-либо проблемы с доступом к частному варианту? Нужен ли префикс или пункт «это»? Я попробовал это-> current-> bias_frag (li, fi); что не помогает
Заранее спасибо.
Скорее всего, что вы непреднамеренно наложение указателя продолжается. Один из li
или же fi
указатели указывают на то же место, что и ¤t
поэтому при разыменовании и назначении им внутри bias_frag
ты случайно перезаписываешь current
или часть этого.
Чтобы это исправить, вам нужно выяснить, почему вы получаете псевдонимы-указатели, отслеживая поток данных в обратном направлении. Для начала проверьте уровень предупреждений вашего компилятора и исправьте все предупреждения.
Не пытайтесь обойти это, сохраняя значение current
и восстановление его — это просто повязка над гораздо более серьезной проблемой, а не долгосрочное решение. Вы уже вошли в страну неопределенного поведения, и попытка откопать себя не сработает.
Других решений пока нет …