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*myarray=malloc(5*sizeof(int))
    声明一个变量,该变量是指向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的大小,你应该能够根据语言规范说出一个数字,而不是操作系统或编译器是如何工作的。此外,您对内存组织方式的控制非常有限,即使是内联选项,它也不过是编译器的提示。