简体   繁体   中英

Why is garbage value being assigned to an already declared variable in the code below?

This is a bit of a complicated problem to describe and it's been extremely frustrating to debug. This is for an assignment i'm working on, so please don't exactly fix my code but perhaps provide some guidance.

I'm creating an array of *card_t pointers, then feed through input redirection a series of data which are credit cards, these have: an encrypted card ID (8 char), a daily limit and transaction limit. The %%%%%% to signify the end of the input. The input are sorted alphabetically.

The inputs would look something like:

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

The struct i use looks like this:

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

Stage_one of the code:

Allocates memory for the first struct pointer, then we read the first line of input.


/*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);
}

Stage 2 does the same but will read everything up to the %%%%%% separator, this is when it gets extremely weird. For example, using sample input (outputs are at the end of the post):

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

Everything prints out as expected except the last 2 iterations, hence for the last line of input and when i assign NULL to the final pointer to indicate the read has terminated. The output for accounts[0]->id becomes some random value.

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++;
    };
}

What makes it so frustrating thought is that if use this as input:

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

it works perfectly fine, so i'm completely confused at this point. I thought perhaps is because the time i get wrong output is due to having a number as the first char, but that really shouldn't be a problem, since after change the '3' to a random letter, i still get the problem. I tried with removing the first line, problem still occurs, first struct pointer gets altered somehow. Then i tired adding the "3tu2iywy" into the second set of input as first line, the problem then occurs again.

Here's the output, after calling a function that prints every attribute of each struct in the array.

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 for the first output is always something different, also Daily Limit sometimes become 0, sometimes doesn't. The error is really random, which makes it so frustrating. Using the second set of inputs i get what is expected:

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
==============================

Solved it, thanks to some of the suggestion, while working on the Minimal Reproducible Example it brought to my attention that I completely forgot to realloc additional memory in the main function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM