每当我将输入存储在char *中的已分配空间之上时,我就会收到free()错误。下面是错误:
*** Error in ./input': free(): invalid next size (fast): 0x09713008 ***
当我删除free()时,即使我输入超过分配的大小,程序也能完美运行。为什么会这样?我该怎样预防呢?这是我的参考代码:
int main(void){
float x; // used to store the float the user entered.
char c; // character used to check if the user entered a character after the float
int loop=0;
char * usr_input = malloc(50); //allocates memory to store the string from the stdin
// loops until the user enters a float and only a float
do{
//gets the input string from stdin
scanf("%s",usr_input);
if(usr_input==NULL)
printf("You've entered a large number that isnt supported. Please use at most 5 digits\n");
// parses the input received and checks if the user entered a float and only a float.
// breaks the loop if they did
else if(sscanf(usr_input,"%f %c",&x,&c) == 1){
if (x!=inf)
loop=1;
else
printf("Input was too large. Try again");
}
// tells the user they entered invalid input. Loop value doesnt change so function loops again
else{
printf("Invalid input. Try again\n");
}
}
while(loop==0); // condition for the loop
free(usr_input);//crashes here
return x; // returns the valid float that was entered
}
答案 0 :(得分:5)
当我删除free()时,即使我输入超过分配的大小,程序也能完美运行。
输入超过分配的大小称为未定义的行为。这是一个错误,尽管您的程序可能看起来运行良好"。
未定义行为的主要问题是您的程序没有快速失败。从本质上讲,对未定义行为的惩罚会延迟到将来的某个时间 - 例如,当您再次分配时,或者当您自由时。
malloc
在已分配的块中存储一些特殊信息,以便free
运行。 " nvalid next size"错误通常意味着您的代码已经写入了一些隐藏的数据块。
要解决此问题,您需要更改代码,使其永远不会超过分配的长度。如果您无法准确检测需要更改的位置,请考虑使用valgrind或其他内存分析器。
要防止scanf
写入已分配的大小,请使用格式字符串中的大小:
scanf("%49s",usr_input); // Pass 49 for the length, because you have 50 bytes, and you need 1 byte for '\0'
答案 1 :(得分:1)
即使我输入的内容超过了,该程序也能完美运行 分配大小。
不,它没有完美运行。实际上,您得到的错误是由写入超出分配缓冲区的边界引起的。它是一个缓冲区溢出并引入了未定义的行为。您的程序可能会工作或可能会立即崩溃,但在大多数情况下,它会导致以后出现问题,这些问题可能看起来完全不相关,因此很难识别和纠正。
确保分配足够大的缓冲区,以免覆盖它。
另一方面,在堆上分配小缓冲区是没有意义的。它可以是堆栈上的静态缓冲区,您可以避免内存分配和释放问题。