2014-01-06 2 views
0

У меня есть указатель на структуру.Указатель необъяснимо изменяемый

typedef struct anything{ 
    char text[MAXI]; 
    int any; 
}Item; 

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

void adding(){ 
    Item *x = malloc(sizeof(Item)); 
    printf("Enter an integer."); 
    scanf("%d", (&x->any)); 
    printf("Enter a string."); 
    scanf("%s", (&x->text)); 
    printf("Which set would you like to add the Item to A/B?"); 
    char inp1 = 0; 
    while ((inp1=0),scanf("%s", &inp1) == 1 && (inp1 != 'A') && (inp1 != 'B')){ 
     printf("Set does not exist\n"); 
    } 
     if('A' == inp1) 
      add(A, x); 
     else 
      add(B, x); 

    flush(); 
    instructs(); 
} 

При приеме ввода (в то время цикла), указатель х модифицируется от 0x570ff8 к 0x57f00, который будет указывать на то мусор вместо ввода запрошенной ниже.

Почему изменяется указатель?

спасибо.

Функция дополню:

void add(Array *S,Item *x){ 
    bool rep = false; 
    int i = 0; 
    for(i = 0; i<=(S->size); i++){ 
     if(compStructs(*x,*(S->arr+i))) 
      rep = true; 
    } 
    if(rep == false){ 
      x = realloc(S->arr, (S->size+1)*sizeof(Item)); 
      (S->size)++; 
      printf("Item has been added"); 
    } 
    else 
     printf("The item is already in the set."); 

} 
+0

'(INP1 = 0)' 'Так что, когда (INP1 = 0)' 'будет 'A''? Или эта модификация не является одной последовательностью? – dhein

+0

Показать код для 'add()'. –

+0

inp1 используется для проверки того, что scanf считывает 1 элемент. Inp1! = A и inp! = B также используются для уведомления пользователя при вводе неверного ввода. – user2035045

ответ

0

Это:

char inp1 = 0; 

    while ((inp1=0),scanf("%s", &inp1) == 1 && (inp1 != 'A') && (inp1 != 'B'))... 

Вы используете формат строки спецификатор (%s), но чтение в символ. Даже если вы просто набираете один символ, scanf будет пытаться сохранить строку с нулевым завершением в памяти, на которую указывает &inp1.

Эта память находится в стеке - как и указатель x. Таким образом, x, вероятно, поврежден scanf. Если вы посмотрите на изменение значения, вы увидите, что нижний байт адреса обнуляется. Это может быть нулевым терминатором.

Чтобы исправить, изменить ваш sscanf использовать формат символов спецификаторов: -

scanf("%c", &inp1) 
+0

Спасибо за ваш четкий ответ. Относительно небольшая проблема, которую я получаю сейчас, заключается в том, что printf в цикле while обращается за 1 раз до того, как пользователь запрашивает его ввод.Кроме того, когда пользователь вводит недопустимый ввод, указанный циклом while, printf печатается 2 раза. – user2035045

+0

@ user2035045 - Это будет потому, что первые два 'scanf' оставляют новую строку, скрывающуюся во входном буфере. Вам может быть лучше использовать 'fgets()', затем 'sscanf'. См. Этот вопрос. http://stackoverflow.com/questions/5918079/fgets-doesnt-work-after-scanf – Roddy

0

Одна ошибка:

scanf("%s", (&x->text)); 

, который должен быть

scanf("%s", x->text); 

потому x->text уже указатель.

Другая ошибка:

scanf("%s", &inp1) 

, которые должны быть:

scanf("%c", &inp1) 

, потому что вы читаете один символ.

+0

Ранее я использовал scanf («% s», (x-> текст)); но я получал ошибку SIGSEGV Segmentation Fault. – user2035045

+0

@ user2035045 что такое MAXI? – HAL9000

+0

MAXI - это всего лишь int, определяющий максимальное значение. – user2035045

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