在这个答案中:https://stackoverflow.com/a/8547993/5324086
该人已经通过两种方式在HEAP上完成了数组分配:
int main(){
const int n = 100000;
#ifdef ALLOCATE_SEPERATE
double *a1 = (double*)malloc(n * sizeof(double));
double *b1 = (double*)malloc(n * sizeof(double));
double *c1 = (double*)malloc(n * sizeof(double));
double *d1 = (double*)malloc(n * sizeof(double));
#else
double *a1 = (double*)malloc(n * sizeof(double) * 4);
double *b1 = a1 + n;
double *c1 = b1 + n;
double *d1 = c1 + n;
#endif
}
两种分配方式有什么区别?
else块中的第二个方法是否以连续的方式分配?
答案 0 :(得分:2)
(我专注于Linux的观点;使其适应您的operating system和/或编译器实现)
您问题中的代码具有类似C的外观。正版C ++将使用new
,即非ALLOCATE_SEPARATE
情况下的
double *a1 = new double[4*n];
double *b1 = a1 + n;
如果内存分配失败,您将获得std::bad_alloc例外。
两种分配方式有什么区别?
ALLOCATE_SEPARATE
案例正在对malloc
进行四次调用。请注意:
每个人malloc
都可能失败,您应该检查一下,例如与
double *a1 = (double*)malloc(n * sizeof(double));
if (!a1) { perror("malloc a1"); exit (EXIT_FAILURE); };
假设您需要一些C代码。并且malloc
可以失败,例如当内核无法提供更多虚拟内存时,例如因为mmap(2)失败,已达到一些限制(请参阅getrlimit(2) ...),交换空间已用尽(禁用内存过量使用)等等....阅读paging &安培; page cache以及malloc(3)的手册页,特别是 NOTES 部分...... BTW,您的计算机有有限资源,所以他们可以溢出来了。在便宜的笔记本电脑上,您在2015年无法成功malloc
10TB的内存(并可靠地使用内存区域)。当然n = 100000
malloc
将<通常成功。
实际上malloc
可能会失败,如果你要求很多的内存(千兆字节),但有些操作系统有memory overcommitment(我个人不喜欢这个功能)并在我的Linux系统上禁用)并给你一些指针,即使没有足够的空间用于巨大的内存区域
在不太可能的情况n * sizeof(double)
溢出size_t
,灾难将会发生。
非ALLOCATE_SEPARATE
要求malloc(n * sizeof(double) * 4)
并且可能会溢出较小的n
值(实际上仍然非常大)。 * 4
是必需的,因为我们要求足够的空间来容纳四个不同的非aliasing pointers及其非重叠的内存区域。
else块中的第二个方法是否以连续的方式分配?
当然是(并且正如我所说的那样,n
可能会溢出或失败,但{32} Linux {(1}}上的n * sizeof(double) * 4
可能会溢出或失败。 )平板电脑大于例如3千兆字节,甚至可能是1千兆字节。
实际上,您应该使用C ++ 11 containers和代码:
n * 32
向量的数据将位于堆中,#include <vector>
int main(){
const int n = 100000;
std::vector<double> vec(n);
的析构函数将释放它。
当然,heap数据是在address space virtual memory的process中分配的(在Linux上,可能使用mmap(2) - 或者有时候vec
- syscall)。