C++ C编程堆栈和堆数组声明
假设我将一个数组声明为C++ C编程堆栈和堆数组声明,c++,c,C++,C,假设我将一个数组声明为intmyarray[5] 或者将其声明为int*myarray=malloc(5*sizeof(int)) 两个声明是否设置了相同的内存量(字节数)? 不考虑前一个声明用于堆栈,后一个声明用于堆 谢谢大家! 有一个根本性的区别,在使用myarray的方式上可能并不明显: int-myarray[5]声明一个由五个整数组成的数组,该数组是一个自动变量(未初始化) int*myarray=malloc(5*sizeof(int))声明一个变量,该变量是指向int的指针(也
intmyarray[5]
或者将其声明为int*myarray=malloc(5*sizeof(int))
两个声明是否设置了相同的内存量(字节数)? 不考虑前一个声明用于堆栈,后一个声明用于堆
谢谢大家! 有一个根本性的区别,在使用myarray的方式上可能并不明显:
声明一个由五个整数组成的数组,该数组是一个自动变量(未初始化)int-myarray[5]
声明一个变量,该变量是指向int的指针(也作为自动变量),该指针使用库调用的结果初始化。该库调用承诺使生成的指针指向一个足够大的内存区域,该区域足以存储五个连续整数int*myarray=malloc(5*sizeof(int))
a[i]
与*(a+i)
相同的约定,您可以以相同的方式使用这两个变量,即myarray[i]
。这当然是故意的
如果您正在寻找差异,那么以下可能会有所帮助:五个整数的数组是一个单一对象,并且它有一个确定的大小。相反,malloc
library调用不会创建任何对象。它只是留出足够的内存(并适当对齐),但它可以分配更多的内存
<>(C++中当然还有内存和对象之间的区别) 简短回答:不,后者通常使用一个较小的大内存。 长答覆:
内存管理肯定会使用一些额外的内存来管理返回的指针,并能够跟踪它,稍后再释放它,然后声明一个指向该内存的额外指针。所以它的实际内存是
sizeof(int*)+malloc\u开销。但在第一种情况下,您只使用5个int(可能加上对齐)。两者都不能保证精确分配5*sizeof(int)
字节,尽管两者都会给您至少这么多的空间(假设没有分配失败或堆栈耗尽)
在第一种情况下,stack变量可能被对齐填充和/或stack canaris(取决于编译选项)包围。这可能会导致堆栈指针调整超过5*sizeof(int)
字节
在第二种情况下,在堆栈上分配一个int*
(sizeof(int*)
bytes),加上malloc
返回的空间malloc
可能会以分配跟踪结构、对齐填充、链表指针等形式分配额外的内存。因此,在这种情况下,也不能保证准确分配5*sizeof(int)
字节
如果您希望非常精确地了解内存使用情况,则mmap
功能允许您从操作系统请求虚拟内存页面。以这种方式请求的内存将正好是您请求的内存量(忽略内核中用于跟踪这些分配的空间)。动态分配将至少需要几个额外字节;但是,除了5个int
大小的元素之外,指针变量还有许多字节,可能还有一些额外的字节来跟踪分配区域的大小,以便它可以正常地空闲你也可以从上面的注释中使用<代码> int *MyReals:new int(5)< /Cord>,Cnew中没有关键字“new”。我还想添加一个事实,即如果你使用C++,并且使用指针,你可能想使用引用来避免讨厌的行为。特别是在声明期间只修改指针值的情况下。根据“equal amount of memory”语句,您可能会“看到”malloc可能会消耗更多内存或根本不消耗内存。通常情况下,内存是通过分页提供给应用程序的,如果从外部关注为程序标记的内存消耗,则可能会看到分配了整个页面(应用程序通常需要更多堆空间)或没有页面(应用程序在现有页面中已经有足够的可用空间用于阵列)1.再加上一个最完整的答案,我认为这个回答有点夸张,或者你是对的,但问题没有解释得那么清楚。你基本上是在解释幕后发生的事情,但这不是他在这里问的,如果我使用一种语言,我问你int的大小,你应该能够根据语言规范说出一个数字,而不是操作系统或编译器是如何工作的。此外,您对内存组织方式的控制非常有限,即使是内联选项,它也不过是编译器的提示。