为什么在下面的代码中将垃圾值分配给已声明的变量?
Why is garbage value being assigned to an already declared variable in the code below?
这个问题描述起来有点复杂,而且调试起来非常令人沮丧。这是我正在处理的作业,所以请不要完全修复我的代码,但也许可以提供一些指导。
我正在创建一个 *card_t 指针数组,然后通过输入重定向提供一系列信用卡数据,这些数据具有:加密的卡 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;
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] = '[=12=]';
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 阶段做同样的事情,但会读取直到 %%%%%% 分隔符的所有内容,这是它变得非常奇怪的时候。例如,使用示例输入(输出在 post 的末尾):
3tu2iywy 10000 800
ceww0p66 150 100
v0xyil5t 3000 500
vb3dtxp0 5000 300
xnwxw8tl 2000 800
%%%%%%%%%%
除最后 2 次迭代外,所有内容均按预期打印,因此对于输入的最后一行以及当我将 NULL 分配给最终指针以指示读取已终止时。 accounts[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,有时不变成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
==============================
解决了它,多亏了一些建议,在处理最小可重现示例时它引起了我的注意,我完全忘记了在主函数中重新分配额外的内存。
这个问题描述起来有点复杂,而且调试起来非常令人沮丧。这是我正在处理的作业,所以请不要完全修复我的代码,但也许可以提供一些指导。
我正在创建一个 *card_t 指针数组,然后通过输入重定向提供一系列信用卡数据,这些数据具有:加密的卡 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;
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] = '[=12=]';
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 阶段做同样的事情,但会读取直到 %%%%%% 分隔符的所有内容,这是它变得非常奇怪的时候。例如,使用示例输入(输出在 post 的末尾):
3tu2iywy 10000 800
ceww0p66 150 100
v0xyil5t 3000 500
vb3dtxp0 5000 300
xnwxw8tl 2000 800
%%%%%%%%%%
除最后 2 次迭代外,所有内容均按预期打印,因此对于输入的最后一行以及当我将 NULL 分配给最终指针以指示读取已终止时。 accounts[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,有时不变成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
==============================
解决了它,多亏了一些建议,在处理最小可重现示例时它引起了我的注意,我完全忘记了在主函数中重新分配额外的内存。