malloc是动态内存分配吗?

Is malloc dynamic memory allocation?

一位讲师告诉我 p = (int*)malloc(5 * sizeof(int)) 不是 动态内存分配,p=(int*)malloc(n * sizeof(int)) 是动态内存分配。

老师在讲基本的数据结构,在教数组。他曾告诉我们使用 int arr[100] 语法创建数组的传统方法,但随后他向我们介绍了 malloc。

根据他的说法,内存大小不会改变,我猜它不是动态的。

根据我从 Internet 上收集到的信息,malloc 在运行时分配内存,并且在运行时分配内存时是动态内存分配。所以我认为 malloc 语句都是动态内存分配。我的推理有问题吗?

通常,我们确实将对 malloc 的调用称为 动态 分配,无论您使用的是变量还是常量。即使是 malloc 也这样称呼它:

malloc, free, calloc, realloc - allocate and free dynamic memory

因此,对于您的讲师声明:

The instructor was talking about basic data structures and was teaching arrays. He had told us the traditional way to create arrays using the int arr[100] syntax, but then he introduced us with malloc.

According to him as the memory size doesn't change it's not dynamic I guess.

好吧,从某种意义上说,如果您以更一般的方式严格看待“动态”的含义,他说得有道理。现在我们有一个约定,调用所有 malloc 动态分配。这个约定本可以是你的老师声称的方式,没有任何问题。但事实并非如此。

另外,按照你老师的推理,使用VLA:s(变长数组)或alloca带变量会被认为是动态分配,但事实并非如此。 VLA 可以这样声明:int arr[n],或者它是 alloca 等效的:int *arr = alloca(n*sizeof(*arr)).

所以即使你可以争论你的老师有一个观点,这只会引起混乱,因为它违背了惯例。

此外,使用 malloc 最动态的一点是可以稍后调整分配的大小。你不能用数组做到这一点,甚至 VLA:s。而且你不能对你用 alloca.

分配的内存执行此操作

但作为旁注,如果你的老师教你写作,我确实质疑他们的能力

p = (int*)malloc(n * sizeof(int)) 

而不是

p = malloc(n * sizeof(*p))
  1. 转换不是必需的,只会增加混乱
  2. 使用 sizeof(*p) 而不是 sizeof(int) 更安全

相关:Do I cast the result of malloc?

I was told by an instructor that p = (int*)malloc(5 * sizeof(int)); is NOT dynamic memory allocation and that p = (int*)malloc(n * sizeof(int)); is dynamic memory allocation

从某种意义上说,这是一个基于意见的问题,因为没有义务将其称为一个或另一个,这主要基于惯例。也就是说,我完全不同意该声明有一定正确性的观点,即使假设引用可能是内存块的大小依赖于一个常量值。

只有当您使用常量或变量值时,这两个表达式才应限定为动态内存分配。在我看来,否则只能说是错误的。

这两个内存块分配以后仍然可以更改,在运行时环境中,因此它们是动态的,而在数组声明中,即int arr[100]分配的内存是固定的,不能更改,因此它是不是动态的。

但是,在使用常量或变量方面存在差异,显而易见的是,能够为变量赋值,这将在运行时确定内存块的大小。正如 非常准确地指出的那样,使用常量作为内存块大小的决定因素允许编译器在某些情况下优化 malloc,考虑到它可能是一个昂贵的函数,这是有意义的.

除此之外,这些陈述大体相似。在这两种情况下,您都可以在分配后的运行时调整内存块的大小。

关于正确使用 malloc 的一些很好的注意事项,我强烈建议您遵循它们,事实上整个答案非常好,如果你觉得舒服,你就能把问题弄清楚。

要么你误解了你的老师试图表达的观点,要么你的老师表达他的观点非常非常糟糕(坦率地说,这种情况并不少见,尤其是在教授 C 语言时)。

您问题中的两个 malloc 调用都是动态内存分配。唯一的区别是第一种形式每次执行时分配一个已知的、固定数量的内存,而第二种形式每次执行时可以分配不同的内存量。这并不能使第一种形式不是动态分配。

这两种情况下的内存都可以通过调用 realloc.

调整大小

作为文体说明,您不必将 malloc 的结果转换为 C1。写

就少了eye-stabby
p = malloc( 5 * sizeof *p ); 

p = malloc( n * sizeof *p );

sizeof *psizeof (int) 相同(假设 p 声明为 int *p)。这使维护更容易,因为您不必多次重复类型信息。


  1. 在 C++ 中不是这种情况,但是如果您正在编写 C++,则无论如何都不应该使用 malloc

C 标准没有定义术语“动态内存分配”。所以我们不能采用 C 标准并查找什么是动态内存分配。

C 标准讨论“内存管理函数”(即 aligned_alloc、calloc、malloc、realloc 和 free)。当使用这些函数时,它通常称为动态内存分配,但 - 重复一遍 - 它不是标准中的术语。

该标准谈到“对象的生命周期”。使用上述内存管理功能之一创建的对象据说具有“分配的存储持续时间”(这意味着它存在直到您的代码释放它)。

问题中的两行代码都使 p 指向具有“已分配存储持续时间”的对象。

我的猜测是你误解了你的老师,即误解了“动态”的含义。也许你的老师谈到了分配对象的大小,即:

p = (int*)malloc(5 * sizeof(int));   // Here the size is static - always 5 ints

p = (int*)malloc(n * sizeof(int));   // Here the size is dynamic (aka depends on n)

注意:C 中不需要强制转换,即 (int*)