繁体   English   中英

关于C语言中的malloc()和free()

[英]about malloc() and free() in C

我有以下C代码:

#include<stdio.h>
#include<stdlib.h>

typedef struct node
{
    int a;
}node;

int main()
{
    node * n;

    printf("\n%d\n",n->a);

    n  = (node *) malloc ( sizeof( node ));

    printf("\n%d\n",n->a);
    n->a = 6;
    printf("\n%d\n",n->a);
    free(n);
    printf("\n%d\n",n->a);
    n->a = 4;
    printf("\n%d\n",n->a);
    return 0;
}

获得的输出为:

1314172

0

6

0

4

我的问题是什至在free(n)之后,为什么n-> a = 0,我们又如何将它重新分配为n-> a = 4的任何值?

不释放使n指向的内存块无效吗?

free(n);
n->a = 4; // is not guaranteed to work, might crash on some implementations

调用未定义的行为。

为什么n-> a = 0,我们又如何将其重新分配为n-> a = 4之类的任何值?

那是因为未定义行为意味着任何事情都会发生。 您不能依靠它。

PS:请勿编写此类代码。

编辑

乔纳森(Jonathan)注意到,您的代码在free()之前取消调用n ,然后取消引用n

node * n; //n is not initialized
printf("\n%d\n",n->a);  //dereferencing a wild pointer invokes UB.

重复使用释放的指针类似于为您租用的汽车制作钥匙的副本,将汽车交还,然后在您将汽车交还给租车地点后尝试使用该钥匙进入汽车。 您也许可以摆脱它,但是您不应该这样做,而且它经常会给您带来麻烦。

不,免费可能对关联的内存没有任何作用。 引用它是无效的。 其他进程/您的进程可能已覆盖内存,或者,如果您不走运,数据可能就如您所愿。

由您决定是否不引用释放的内存。

当取消引用未分配内存的指针时,该行为是不确定的。 这意味着它可以做任何事情。 它可能会触发错误,或者可能会执行其他操作。

在大多数情况下,如果您free一些内存,则不会立即重新使用该内存,并且操作系统不会立即将其回收。 这意味着您的应用程序仍然可以访问该内存,并且仍将包含其先前的值。 您通常可以在没有错误的情况下对其进行读取或写入,但是您一定不能依赖此行为

如果您在许多不同的环境中运行此代码,您会发现在某些环境中它始终可以工作,在某些环境中它总是会触发错误,但是在许多其他环境中,它“大部分时间”都可以工作。 这使得C很难调试! :)

内存块被释放。 那并不意味着你不能写它。 这意味着您不得写信。 机器不会阻止您执行此操作(通常,有些工具(例如电围栏)会阻止它运行)

如您将来所见; 您最终会意外地这样做; 通常会发生坏事(tm)

在大多数针对带有MMU的硬件(例如x86)的操作系统上,实际读取内存错误的唯一方法是未映射应用程序地址。 由于MMU没有告诉它与物理地址相关联的数据的条目,该数据与应用程序所请求的逻辑地址相关联,因此MMU引起中断,操作系统接管该操作。

但是大多数操作系统除了为应用程序提供所需大小的连续内存块外,并没有为代表应用程序管理内存。 操作系统也不允许应用程序在MMU中混乱,因为大多数MMU不够智能,无法让应用程序安全地执行操作而不会对其他程序造成负面影响(意外或恶意)。

因此,当您使用malloc()某些操作时,如果您的应用尚未在其现有地址空间中放置该位置,它将向操作系统询问更多信息,但是当您稍后使用free()时,除非该操作恰好位于在应用程序地址空间的最末端,您无法将其退还给操作系统,以使该内存区域在尝试读取时会导致错误。

有一些方法可以做到这一点,例如,使用mmap() ,但这并不是使用该函数的正确原因。

大多数操作系统将分配一定的最小空间,该最小空间将等于或大于您请求的空间。 拨打免费电话后,该空间将不会返回操作系统,而是随身携带以备将来使用。 因此,您可以摆脱上面编写的内容。

但是严格来说,这被归类为“未定义”行为。 但是您大多数时候都可以摆脱它。 只是不要养成习惯;)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM