假设我将数组声明为int myarray[5]
或将其声明为int*myarray=malloc(5*sizeof(int))
两个声明是否会在字节数中设置相等的内存量? 不考虑前一个声明是针对堆栈而后者是堆栈。
谢谢!
答案 0 :(得分:5)
存在根本区别,您使用 myarray
的方式可能并不明显:
int myarray[5];
声明一个包含五个整数的数组,该数组是一个自动变量(并且未初始化)。
int * myarray = malloc(5 * sizeof(int));
声明一个变量,它是一个指向int的指针(也作为一个自动变量),并且该指针是用库调用的结果初始化的。该库调用承诺使得结果指针指向一个足以存储五个连续整数的内存区域。
由于指针算法,数组到指针衰减以及a[i]
与*(a + i)
相同的约定,您可以以相同的方式使用这两个变量,即myarray[i]
。这当然是设计的。
如果你正在寻找差异,那么可能有以下帮助:五个数组的数组是单个对象,并且它具有一定的大小。相比之下,malloc
库调用不会创建任何对象。它只是放置足够的内存(并且适当对齐),但它可以分配更多的内存。
(在C ++中,当然还有内存和对象之间的区别。)
答案 1 :(得分:3)
两者都不能保证准确分配5*sizeof(int)
字节,尽管两者都会给你至少那么多空间(假设没有分配失败或堆栈耗尽)。
在第一种情况下,堆栈变量可能被对齐填充和/或堆栈canaries(取决于编译选项)包围。这些可能导致堆栈指针调整超过5*sizeof(int)
个字节。
在第二种情况下,您在堆栈上分配int *
(sizeof(int *)
字节),加上 malloc
返回的空间。 malloc
可以以分配跟踪结构,对齐填充,链接列表指针等形式分配额外的内存。因此,在这种情况下,您也不能保证准确分配5*sizeof(int)
个字节。
如果您想要非常准确地了解内存使用情况,mmap
功能允许您从操作系统请求虚拟内存页面。您以这种方式请求的内存将正是您请求的数量(忽略内核中占用的空间以跟踪这些分配)。
答案 2 :(得分:2)
简答:通常情况下,后者使用较小的较大内存。
长答案:
内存管理肯定会使用一些额外的内存来管理返回的指针并能够跟踪它,并在以后释放它并声明一个指向该内存的额外指针。所以它的实际内存是sizeof(int*) + malloc_overhead
。但在第一种情况下,你恰好使用5 int(可能还有对齐)。
答案 3 :(得分:2)
动态分配至少需要几个字节;但是除了5 int
大小的元素之外,指针变量还有很多字节,并且可能还有一些额外的字节用于跟踪分配区域的大小,以便它可以free
正确。