C 为什么在下面的代码中将垃圾值分配给已经声明的变量?

C 为什么在下面的代码中将垃圾值分配给已经声明的变量?,c,pointers,struct,garbage,C,Pointers,Struct,Garbage,这是一个需要描述的有点复杂的问题,调试起来非常令人沮丧。这是我正在做的作业,所以请不要完全修改我的代码,但也许可以提供一些指导 我正在创建一个*卡指针数组,然后通过输入重定向提供一系列数据,这些数据是信用卡,它们有:加密的卡ID 8字符、每日限额和交易限额。%%%表示输入结束。输入按字母顺序排序 输入看起来像: 2uu2iywy 7000 120 op81hs12 1000 50 zh8102ol 4300 90 %%%%%%%% 我使用的结构如下所示: typedef struct{

这是一个需要描述的有点复杂的问题,调试起来非常令人沮丧。这是我正在做的作业,所以请不要完全修改我的代码,但也许可以提供一些指导

我正在创建一个*卡指针数组,然后通过输入重定向提供一系列数据,这些数据是信用卡,它们有:加密的卡ID 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;
阶段\代码之一:

为第一个结构指针分配内存,然后读取第一行输入


/*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
==============================
第一次输出的卡ID总是不同的,而且每日限制有时变为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
==============================

多亏了一些建议,我解决了这个问题。在处理最小可复制示例时,我注意到我完全忘了在主函数中重新分配额外内存。

为什么不使用scanf%s读取每行的第一个字,而不是编写自己的getchar循环?演示如何调用stage_2。我怀疑问题在于您分配作为参数传递的数组的方式。此外,数组索引从0开始,为什么要初始化I=1?这里没有足够的信息来了解您可能做错了什么。请使用其他人可以按原样编译和运行的方法更新您的问题,以获得与您相同的结果。您还存在内存泄漏。当read_one_card返回0时,您分配账户[i]=NULL;但是你永远不会释放你分配的内存。