Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 动态内存分配是如何工作的?_C_Dynamic Memory Allocation - Fatal编程技术网

C 动态内存分配是如何工作的?

C 动态内存分配是如何工作的?,c,dynamic-memory-allocation,C,Dynamic Memory Allocation,考虑以下代码: int *p = malloc(4); int *i = malloc(4); 现在,已经分配了一块内存(在上述情况下为4字节),并且基址存储在p中 在int*i=malloc(4)行中分配内存时 编译器是如何知道这段内存已分配的? 为什么不分配与int*p=malloc(4)分配的内存块相同?当您在代码中使用类似malloc的例程,并将代码编译和链接到可执行程序中时,软件例程库也会链接到您的代码中。该库中的例程具有用于从操作系统请求内存的软件,用于将内存划分为若干部分,并在使

考虑以下代码:

int *p = malloc(4);
int *i = malloc(4);
现在,已经分配了一块内存(在上述情况下为4字节),并且基址存储在
p

int*i=malloc(4)
行中分配内存时

编译器是如何知道这段内存已分配的?


为什么不分配与
int*p=malloc(4)
分配的内存块相同?

当您在代码中使用类似
malloc
的例程,并将代码编译和链接到可执行程序中时,软件例程库也会链接到您的代码中。该库中的例程具有用于从操作系统请求内存的软件,用于将内存划分为若干部分,并在使用
malloc
请求时将其释放,以及跟踪使用
free
释放的内存和释放的内存


因此,每当你编译一个非常小的程序时,你都会得到一个很大的附加软件库,人们已经使用了很多年。

当你在代码中使用像
malloc
这样的例程,并将代码编译和链接到一个可执行程序中时,一个软件例程库也会链接到你的代码中。该库中的例程具有用于从操作系统请求内存的软件,用于将内存划分为若干部分,并在使用
malloc
请求时将其释放,以及跟踪使用
free
释放的内存和释放的内存


因此,每当你编译一个非常小的程序时,你都会得到一个很大的附加软件库,这些软件是人们多年来开发的。

编译器不负责知道谁拥有哪一块内存,也不负责无意中占用以前分配的内存。这是操作系统工作的一部分。编译器生成汇编代码,在汇编代码中进行适当的系统调用,以从操作系统获取指向动态内存块的指针。为了演示,这里有一个愚蠢的例子:

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

int main(void) {
    int* ptr = malloc(4);
    free(ptr);
    return 0;
}

注意
callq
行。编译器只负责调用适当的系统调用以获取动态内存

编译器不负责知道谁拥有哪一块内存,也不负责无意中占用先前分配的内存。这是操作系统工作的一部分。编译器生成汇编代码,在汇编代码中进行适当的系统调用,以从操作系统获取指向动态内存块的指针。为了演示,这里有一个愚蠢的例子:

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

int main(void) {
    int* ptr = malloc(4);
    free(ptr);
    return 0;
}

注意
callq
行。编译器只负责调用适当的系统调用以获取动态内存

编译器不需要知道。事实上,可以传递任何指向
free
的指针,即使是无效的指针。这导致了一个问题,但C编译器无法阻止您这样做。您作为C开发人员的工作。您的编辑使问题完全不清楚。粗体的句子表达了两种不同的意思,毫无意义。即使在编辑之后,也不取决于编译器本身,而是取决于
malloc
函数的实现。它可以由编译器编写器实现,也可以只调用某些操作系统特定的函数进行分配。C语言规范没有说明标准库函数(如
malloc
)应该如何实现,只说明它们应该如何运行。编译器不需要知道。事实上,可以传递任何指向
free
的指针,即使是无效的指针。这导致了一个问题,但C编译器无法阻止您这样做。您作为C开发人员的工作。您的编辑使问题完全不清楚。粗体的句子表达了两种不同的意思,毫无意义。即使在编辑之后,也不取决于编译器本身,而是取决于
malloc
函数的实现。它可以由编译器编写器实现,也可以只调用某些操作系统特定的函数进行分配。C语言规范没有说明标准库函数(如
malloc
)应该如何实现,只有它们的行为。好吧……你说内核跟踪所有给malloc的内存…???@Comp_sci_学生:C的实现附带了一个通常称为标准C库的软件库。此库将成为程序的一部分。它在相同的进程中运行,使用相同的内存,就像您自己编写的子程序一样。该库中的软件跟踪
malloc
free
的内存。该软件确实从操作系统请求内存,这在您的进程之外。操作系统有自己的软件来跟踪它给进程的内存。@Comp_sci_学生:“内核”这个词有点模糊。今天的操作系统是巨大的,有许多层和子系统。一个称为内核的部分可能是其中的一小部分,也可能是其中的一大部分,而内存管理在某种程度上通常是其中的一部分。好吧……你说内核跟踪提供给malloc的所有内存…???@Comp_sci_学生:C的实现附带了一个软件库,通常称为标准C库。此库将成为程序的一部分。它在相同的进程中运行,使用相同的内存,就像您自己编写的子程序一样。该库中的软件跟踪
malloc
free
的内存。该软件确实从操作系统请求内存,这在您的进程之外。操作系统有自己的软件来跟踪它给进程的内存。@Comp_sci_学生:“内核”这个词有点模糊。今天的操作系统是巨大的,有许多层和子系统。称为内核的部分可能是其中的一小部分,也可能是其中的一大部分