free free不删除分配给指针的内存(int数组),使用免费的两次工作,为什么?

时间:2016-06-16 06:49:37

标签: c arrays pointers memory-management

这是出于好奇,我试图在以前的问题上找到我怀疑的答案,但他们似乎没有回答它。所以问这里,我刚写了一个代码,我试图将内存分配给一个int指针(填充一个数组)并将int值扫描给它。完成数组后,我想删除分配给指针的数据/内存。虽然我的代码工作得很好,但是为什么我仍然可以在free ing 指针之后看到int数组中的值。然而,如果我使用两次免费它会引发错误(这是在单次使用免费后预期的)。这不是一个奇怪的行为吗?我在我的Mac上尝试使用Xcode也在codechef,同样的行为,为什么?

int *num=(int *)malloc(n*sizeof(int));
int i;
for(i=0;i<n;i++)
{
    scanf("%d",&num[i]);        
}    

for(i=0;i<n-1;i++){
    temp = some_function(x);        
}

free(num); 

for(i=0;i<n;i++)
{
    printf("\nnum[%d]= %d\n",i,num[i]);        
}

上面的代码在num []中打印值,理想情况下它不应该。

4 个答案:

答案 0 :(得分:9)

这不奇怪,也不错。在指针上调用free时,您只告诉内存管理器它可以再次使用该部分内存进行另一次malloc调用。它不会删除内容(这将花费额外的时间,没有任何功能)。但是,可以访问它,因为指针仍指向有效地址。它会导致未定义的行为,因为内存管理器可能已将该内存提供给其他一些代码。

第二次调用free会产生错误,因为内存管理器不再知道该指针是否有效(你只是free d!)。实际上,这是未定义的行为

答案 1 :(得分:6)

你的程序很顽皮并且参与未定义的行为

在第一个free之后,内存确实会返回系统,它只是释放内存:

  1. 并不一定清除它
  2. 并不一定会阻止您访问它
  3. 再次释放它会引发错误,因为您已经将其释放回系统。

    这并不意味着您可以再次malloc内存,free,并依赖以后仍可以访问它!

    首先,您看到的行为未定义 - 根据C标准,您的程序并不真正有效。通过编译器,操作系统和环境的特定组合,您可以在空闲后访问该内存的内容,但它可以轻松地中断。此外,&#34;未定义的行为&#34;允许编译器适应各种各样的恶作剧,使后来的代码完全没有达到你所期望的那样。

    其次,在空闲后的任何时刻,内存都可用于后续的malloc。因此,即使您依赖于编译器/ os /环境的行为而不是破坏免费使用后的代码,各种其他进程也可能会用其他内容填充该空间。

    Free-after-free是一个非常大的nono,所以只需释放一次,永远不会访问释放的内存。

    请参阅:https://cwe.mitre.org/data/definitions/416.html了解您可能遇到的安全问题类型。

答案 2 :(得分:1)

程序的行为是未定义

致电free后,您不应再尝试读取该内存。请注意,在同一指针上再次调用free时的行为也是未定义:不要这样做!

没有理由让C运行时过于热心,并且不知何故不允许你明确地做你正在做的事情,因为在编写良好的C程序中它不是最理想的。

答案 3 :(得分:1)

调用free()之后,您已向内存管理员表明您已完成此内存。内存管理器现在可以使用此内存来处理新的分配请求。

如果由于已经有指向内存位置的指针而再次访问同一内存,则这是一种未定义的行为。

在同一内存位置再次调用free()也是一种未定义的行为。