在C中再次调用函数后,变量发生了变化


我创建了一个结构和一个返回该结构的函数。之后,我调用该函数两次,每次都分配给不同的变量。问题是第一个变量在第二次运行后会发生变化。我在这里错过了什么?

代码:

struct text_and_len {
char* text;
int len;
};
struct text_and_len get_text_and_length(){
int len;
scanf("%d ", &len);
char text[len];
fgets(text, len+1, stdin);
return (struct text_and_len) {text, len};
}
void get_input_and_check_is_within(){
struct text_and_len b = get_text_and_length();
printf("%s n", b.text);
struct text_and_len a = get_text_and_length();
printf("%s n", a.text);
printf("%s n", b.text);

这将首先打印b.text,但随后将打印a.text两次。

get_text_and_length()():中使用的这些行

char text[len];
fgets(text, len+1, stdin);//over writes buffer by at least 1, 2 if wanting a C string.  Will cause undefined behavior.(UB)

将潜在地允许用户输入将重写缓冲区的输入。原样代码还包括在其他地方需要变量之前到达生命终点的变量,从而导致可预测但不需要的行为。此外,结构体char* text;中的成员在写入之前需要分配内存。因此也需要释放。

下面是为了解决这些问题而重构的代码,以及对原型和调用方法的一些其他修改,这些修改简化了代码的编写。。。

struct text_and_len {
char* text;
int len;
};
void get_text_and_length(struct text_and_len *b){
printf("Enter max length of input stringn");
scanf("%d ", &(b->len));
//b->text[b->len];//VLA, but has already been declared as char *
b->text = malloc(b->len + 2);//room for NULL terminator AND newline
memset(b->text, 0, b->len+2);//zero variable to all NULL
//fgets(text, len+1, stdin);//text has no memory
//and as is would have over-written 
//buffer - UB
printf("Enter string no longer than max lengthn");
fgets(b->text, b->len+2, stdin);//note len+2 provides room
//for len char + NULL + newline
}
void get_input_and_check_is_within(struct text_and_len *b){
get_text_and_length(b);
printf("max length: %d n", b->len);
printf("text entered:%s n", b->text);
}
int main(void)
{
struct text_and_len a = {0};
get_input_and_check_is_within(&a);
free(a.text);//allocated in get_text_and_length()
return 0;
}

最新更新