调用 fopen 时的内存分配不清楚

use*_*508 1 c memory-management

1. File *fp;
2. fp = fopen ("/etc/myfile.txt", "w");
3. fclose(fp);
Run Code Online (Sandbox Code Playgroud)

现在

我读了这个

在语句 1 中,在堆栈上为指针创建了类型为“FILE”的 4 字节内存。

在语句 2 中,在堆上分配了内存 = 'sizeof(FILE)',并将其地址分配给指针 'fp'。

有人可以对语句 2 进行更多解释。我们是否为所有文件分配了相同的堆大小?操作系统如何知道它应该分配的 FILE 的大小?
在低级别,st 2 中究竟发生了什么。

abl*_*igh 5

步骤 1 在堆栈上分配一个指针(如果它在函数中),或者如果在函数外部,则将引用全局空间(数据段或类似)中现有的保留位置 - 在后一种情况下,这是在编译时保留的,即由编译器决定,而不是在运行时分配。指针在 32 位环境中为 4 个字节,在 64 位环境中为 8 个字节。

第 2 步调用fopen()。该行本身不分配内存,但 的实现fopen()可能会这样做。你不知道这分配了什么,因为它依赖于实现。但是,您可以非常确定它将分配一个 size 结构sizeof FILE。您还知道这fopen()是用于缓冲 I/O,因此它可能会分配一个缓冲区,或者这可能会在您第一次使用该文件时完成。您无法知道,因为它取决于实现。但是,POSIX<stdio.h>指定了缓冲区的长度,BUFSIZ所以可以肯定的是,当它实际上被分配时,它至少是那个大小,所以当缓冲区被分配时,它至少会在一个内存结构中 size BUFSIZmmapMAP_ANON并保留一个指向它的指针);再次,它依赖于实现。然而,公平的赌注是它在堆上。

第 3 步调用fclose()。这将释放在步骤 2 中进行的分配,但不会释放在步骤 1 中进行的分配(如果有)。

关于“操作系统如何知道FILE'的大小的问题FILE是 C 结构(实际上是typedefa struct)。因此,它的大小对于 C 编译器是已知的,并且将传递给使用的任何分配器,例如堆分配器。如果使用堆分配器,它甚至不会对操作系统可见,因为它将在您的 C 库中处理。

也许您将磁盘上文件的大小与FILE. FILE不是磁盘上的文件,它是一个 C,它是该文件typedef struct的缓冲 I/O 的控制结构,并将包括(例如)文件描述符。该文件(通常)不会完全加载到 RAM 中。它的一小部分(缓冲区)被加载进来,POSIX 标准规定缓冲区应该是BUFSIZ长度。请参阅:http : //pubs.opengroup.org/onlinepubs/009695399/basedefs/stdio.h.html