当我必须指定内存大小时,malloc 数组和常规数组有啥区别?

Posted

技术标签:

【中文标题】当我必须指定内存大小时,malloc 数组和常规数组有啥区别?【英文标题】:What is the difference between malloc array and regular array when in both I have to specify memory size?当我必须指定内存大小时,malloc 数组和常规数组有什么区别? 【发布时间】:2017-07-23 17:14:43 【问题描述】:

malloc()-ed 数组和普通数组有什么区别,例如我必须指定内存大小

char* arr =  malloc(50 * sizeof(char)) 

int arr [50]

【问题讨论】:

charint 是完全不同的类型......无论如何,你不会将苹果与橙子进行比较。 你是什么意思 - 有什么区别?问题不清楚 【参考方案1】:

嗯,有太多的不同。首先,请阅读 arrays are not pointers and vice versa

也就是说,从可用性的角度来看,三个主要区别(我觉得你对此很感兴趣

数组的作用域仅限于其封闭块,但动态分配的内存是有效的,除非手动解除分配。因此,函数的本地数组不能是 retruned,但可以是通过 malloc()-ing 返回的指针。

对于非VLA 的情况,数组大小必须 是编译时常量,但对于malloc(),大小是在运行时指定的。换句话说,对于数组,您需要在编译时知道大小,而对于malloc()-ing,完全有可能在运行时确定请求的大小。

无法调整数组的大小。定义后,它们将使用其大小所需的所有内存。 OTOH,一个malloc()-ed 指针,指向一些内存,根据需要,很可能realloc()-ed 指向其他一些内存。

【讨论】:

此外,分配失败可以通过检查来自malloc() 等的返回值来检测,但分配静态数组或 VLA 失败是无法检测到的 AFAIK。【参考方案2】:

因为数组大小应该在编译时可用,而使用指针让您在运行时确定它的大小。

【讨论】:

也许你应该添加“non-VLA”。 是的,但 VLA 只是一种选择。【参考方案3】:

来自this link:

动态内存分配允许您的程序在运行时获得更多内存空间,或者在不需要时释放它。

简单来说,动态内存分配允许您手动处理程序的内存空间。

Here 您还可以阅读到,在静态分配中,所需的内存由编译器分配,并且必须在编译时知道存储的确切大小和类型。另一方面,在动态内存分配中,在运行时“动态”分配的内存和动态分配的空间通常放置在称为堆或空闲存储的程序段中。

【讨论】:

【参考方案4】:

使用malloc,您使用的大小可以是一个变量!这意味着在执行到达malloc 语句之前,大小可能会根据变量的变化而变化。指定声明数组的大小,否则必须是常量。

int foo = 5;
char bar[foo]; // This will cause a compile error
char bar[5]; // size is fixed, array size specifiers MUST be constant in C  

void some_func (void) 

    // do some work that might change foo, e.g. get a value from user

    char* arr =  malloc(foo * sizeof(char)); //foo is variable, thus the size is variable!

请注意,您说过您曾说过您使用malloc 创建一个数组。这是不正确的。 malloc 只是分配一些连续的内存并给你一个指向该内存开始的指针 - 从技术上讲,这 不是 作为数组的东西(它可以像 是 在很多情况下,但不是所有情况)

【讨论】:

但我不能在运行时从用户那里获得一个 int 并将其分配给一个变量(比如 x),然后声明一个数组 arr[6]; ? 不可以,因为 C 语言不允许数组长度以这种方式可变。在这种情况下使用 malloc 代替 is 虽然是允许的 其实可以char bar[foo] @ChrisTurner 这会为自动(函数范围)数组编译,但会导致全局数组出错。 所以它确实允许数组长度在某些情况下是可变的,这与您之前的评论相反;)【参考方案5】:

主要区别在于动态分配的内存可以根据需要调整大小;数组(静态、自动或可变长度)一旦被实例化就不能调整大小。

次要差异与数组的生命周期有关。在文件范围内声明的数组或使用 static 关键字声明的数组的生命周期会随着程序的生命周期而延长。在函数或块中声明的数组没有 static 关键字的生命周期仅限于其封闭范围的范围(这就是为什么你不能从函数返回指向本地数组的指针- 当函数退出时,数组不再存在)。

动态内存介于两者之间 - 它的生命周期从最初的 *alloc 调用延伸到 free 调用,这可能在不同的函数中。 直接控制它的生命周期。

由于auto(本地)变量的内存通常是如何管理的,自动和可变长度数组通常不能任意大 - 尝试创建大小超过 1 兆字节左右的本地数组可能会导致流行平台上的运行时错误。您通常对动态分配的内存没有这样的限制。

【讨论】:

以上是关于当我必须指定内存大小时,malloc 数组和常规数组有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

new与malloc的区别struct与class的区别

动态内存管理 new 和 delete

剖析C动态内存管理 (malloc,calloc,realloc,柔性数组)

new/malloc

内存空间

为啥尽管我在变量中使用 malloc 分配更多内存,但当我打印变量的大小时,它仍然显示更少的内存/字节? [复制]