Почему значение мусора присваивается уже объявленной переменной в приведенном ниже коде? - PullRequest
0 голосов
/ 28 мая 2020

Это немного сложная проблема для описания, и ее отлаживать было чрезвычайно сложно. Это для задания, над которым я работаю, поэтому, пожалуйста, не исправляйте мой код в точности, но, возможно, дайте некоторые рекомендации. данных, которые являются кредитными картами, они имеют: зашифрованный идентификатор карты (8 символов), дневной лимит и лимит транзакций. %%%%%% для обозначения конца ввода. Входные данные отсортированы по алфавиту.

Входные данные будут выглядеть примерно так:

2uu2iywy 7000 120
op81hs12 1000 50
zh8102ol 4300 90
%%%%%%%%

Структура, которую я использую, выглядит так:

typedef struct{
    char id[ID_LENGTH + 1];
    int daily_limit;
    int transaction_limit;
} card_t;

Stage_one кода:

Выделяет память для первого указателя структуры, затем мы читаем первую строку ввода.


/*reads one card, puts into appropriate struct attribute
    return 1 if read successfully, 0 if reached % split*/
int read_one_card(card_t *one_card) {
    int x, i = 0;
    while(((x = getchar()) != EOF) && (x != ' ')) {
        if(x == '%') return 0;
        if(x != 10) {
            one_card->id[i++] = x;
        }
    }
    one_card->id[i] = '\0';
    scanf("%d", &one_card->daily_limit);
    scanf("%d", &one_card->transaction_limit);

    return 1;
}

void stage_one(card_t **accounts) {

    *accounts = (card_t*)malloc(sizeof(card_t)); //Allocate memory for one account

    read_one_card(*accounts);

    print_header(1);

    printf("Card ID: %s\n", accounts[0]->id);
    printf("Daily limit: %d\n", accounts[0]->daily_limit);
    printf("Transaction limit: %d\n", accounts[0]->transaction_limit);
}

Этап 2 делает то же самое, но будет читать все, вплоть до разделителя %%%%%%, это когда становится очень странно. Например, используя образец ввода (выходные данные находятся в конце сообщения):

3tu2iywy 10000 800
ceww0p66 150 100
v0xyil5t 3000 500
vb3dtxp0 5000 300
xnwxw8tl 2000 800
%%%%%%%%%%

Все распечатывается, как ожидалось, за исключением последних 2 итераций, следовательно, для последней строки ввода и когда я присваиваю NULL для последний указатель, указывающий, что чтение завершено. Вывод для учетных записей [0] -> id становится случайным значением.

void stage_two(card_t **accounts) {
    int i = 1, is_card;
    while(1) {
        accounts[i] = (card_t*)malloc(sizeof(card_t)); 
/*I noticed here, after the above line is run, accounts[0] gets reassign to some garbage value*/
        printf("accounts[0]->id : %s\n", accounts[0]->id);
        if(!read_one_card(accounts[i])){
            accounts[i] = NULL;
            break;
        } 
        i++;
    };
}

Что делает эту мысль такой разочаровывающей, так это то, что при использовании этого в качестве ввода:

ceww0p66 150 100
deww0p11 100 100
eeww0p22 105 101
%%%%%%%%%%

она отлично работает хорошо, так что я полностью запутался на данный момент. Я подумал, что, возможно, это связано с тем, что я получаю неправильный вывод из-за того, что число в качестве первого символа, но это действительно не должно быть проблемой, так как после изменения '3' на случайную букву у меня все еще возникает проблема. Я попытался удалить первую строку, проблема все еще возникает, первый указатель структуры каким-то образом изменен. Потом я устал добавлять «3tu2iywy» во второй набор входных данных в качестве первой строки, проблема возникает снова.

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

Card ID: ーナ
Daily limit: 0
Transaction limit: 800
==============================
Card ID: ceww0p66
Daily limit: 150
Transaction limit: 100
==============================
Card ID: v0xyil5t
Daily limit: 3000
Transaction limit: 500
==============================
Card ID: vb3dtxp0
Daily limit: 5000
Transaction limit: 300
==============================
Card ID: xnwxw8tl
Daily limit: 2000
Transaction limit: 800
==============================

CARD ID для первого выхода всегда отличается, также Daily Limit иногда становится 0, иногда нет. Ошибка действительно случайная, что очень неприятно. Используя второй набор входных данных, я получаю то, что ожидалось:

Card ID: ceww0p66
Daily limit: 150
Transaction limit: 100
==============================
Card ID: deww0p11
Daily limit: 100
Transaction limit: 100
==============================
Card ID: eeww0p22
Daily limit: 105
Transaction limit: 101
==============================

1 Ответ

1 голос
/ 28 мая 2020

Решил его, благодаря некоторым предложениям, во время работы над Минимальным воспроизводимым примером я обратил внимание на то, что я полностью забыл реалло c дополнительной памяти в основной функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...