2015-09-05 3 views
0

Это проблема отладки, которую я пытался решить. Я знаю, что нужно использовать битовую маску, чтобы сделать b равным a. Я проверил с gdb, чтобы найти разницу между a и b. Переменные b и a являются char[] типами и устанавливаются перед достижением «ошибки».указатель на переменную не обновляет переменную при разыменовании

#include <string.h> 

int main() { 
    char a[1] = "a"; 
    char b[1] = "b"; 
    int *x; 
    x = (int *) b; 
    // bug in next line 
    *x = *x & 0xffffffff; 
    return memcmp(a, b, 1); 
} 

До a равна b, я не могу решить эту проблему. Единственное ограничение состоит в том, что ошибка указана в строке, другой код не должен быть изменен. Не существует правила, говорящего, что я не могу добавить строки после ошибки, хотя и до memcmp(). Проблема, которую я нахожу, заключается в том, что ничего, что я делаю с битовой маской, не изменяет значение b, никогда. Я установил точки останова и проверил значение x и *x до и после ошибки, но x, похоже, не меняется.

Breakpoint 1, main() at test.c:9 
9  *x = *x & 0xffffffff; 
(gdb) print (int) a 
$1 = -6922 
(gdb) print (int) b 
$2 = -6921 
(gdb) print (int) x 
$3 = -6921 
(gdb) step 

Breakpoint 2, main() at test.c:10 
10 return memcmp(a, b, 1); 
(gdb) print (int) a 
$4 = -6922 
(gdb) print (int) b 
$5 = -6921 
(gdb) print (int) x 
$6 = -6921 

Я не вижу, как это можно решить по желанию, путем изменения константы в строке, где находится ошибка. Любая помощь, чтобы понять, как использовать x для обновления b с использованием побитовой маски, будет оценена по достоинству.

+0

Как вы отметили C++: не используйте C-style casts. В этом случае вам нужно будет использовать 'reinterpret_cast' для компиляции. Всякий раз, когда вы используете это ключевое слово и не знаете, почему это безопасно, код следует считать ошибочным! –

+0

Я не верю твоему праву. Выход из отладчика несовместим с кодом. –

+0

правильный, это был пример, я превратился в минимальный, полный пример. поэтому показанные целочисленные значения не являются репрезентативными для действительных значений «a» и «b» и т. д. –

ответ

1

Вы пытаетесь изменить адрес b но в

*x = *x & 0xffffffff; 

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

x = x & 0xffffffff; 

И тогда вам нужно переназначить й в б.

Это будет работать от strict aliasing rules.

+0

@mike_b Я обновил свой ответ. – NathanOliver

+0

Что вы подразумеваете под «вне сферы действия»? Это ваша программа ... Измените все, что захотите. (Если это домашняя работа, то проверьте академическую политику честности вашей школы. Вероятно, вам придется ссылаться на этот веб-сайт, когда вы отправляете домашнее задание. И я сомневаюсь, что «размещение вопроса в Интернете и копирование ответа» будет рассмотрен очень благоприятно .) –

+0

Как вы думаете, что я подразумеваю под «вне сферы действия»? Как вы думаете, что я имею в виду, заявив, что это «проблема отладки» или указывая, в какой строке находится «ошибка»? Это проблема (а не домашняя работа, но связанная с учебой в школе), предоставленная мне для решения по инструкциям, что мне нужно только изменить битмаску для ее решения. Поэтому я заявляю: «Я знаю, что нужно использовать битовую маску, чтобы сделать b равным а». Мой вопрос о SO вызывает сомнения, что на самом деле существует решение, потому что '* x' не имеет ничего общего с' b' при изменении. Но лучше спросить, прежде чем требовать у доктора философии, что их логика указателей неверна. –

1

x - указатель; отбрасывая его на int, просто указывается адрес в виде десятичного числа.

a и b - оба массива, которые будут разлагаться на указатель, когда вы выполняете операции, требующие указателя. Отбрасывая их на int, вы снова получаете адрес переменной. Адрес не изменяется при выполнении операции, даже если содержимое с этим адресом изменяется.

С a и b оба меньше, чем int, ваш код, скорее всего, будет испорчен способами, которые чрезвычайно болезненны. Даже если они были правильного размера, это не гарантирует правильное поведение.

Смежные вопросы