为什么 free() 不起作用?

问题描述 投票:0回答:2

每次我将输入存储在 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
}
c malloc free coredump
2个回答
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
投票
即使我输入的内容比 分配的大小。

不,它运行得并不完美。事实上,您得到的错误是由于写入超出了分配的缓冲区的边界而引起的。它是缓冲区溢出并引入未定义的行为。您的程序可能会工作,也可能会立即崩溃,但在大多数情况下,它会在以后引起问题,这些问题可能看起来完全不相关,因此很难识别和纠正。

确保分配的缓冲区足够大,不会覆盖它。

另一方面,在堆上分配那个小缓冲区是没有意义的。它可以是堆栈上的静态缓冲区,您可以避免内存分配和释放问题。

© www.soinside.com 2019 - 2024. All rights reserved.