HEAP 上的数组分配(单独分配与......连续分配?)
Array allocation on HEAP (Separate allocation vs ... contiguous?)
在这个回答中:
此人用两种方式在 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中的第二种方法是连续分配块吗?
(我专注于 Linux 观点;根据您的 operating system and/or 编译器实现进行调整)
您问题中的代码具有类似 C 语言的外观和感觉。正版 C++ 将使用 new
,即在非 ALLOCATE_SEPARATE
情况下类似于
double *a1 = new double[4*n];
double *b1 = a1 + n;
如果内存分配失败,您将得到一个 std::bad_alloc 异常。
What is the difference between the two ways of allocation?
ALLOCATE_SEPARATE
案例正在对 malloc
进行四次调用。请注意:
每个人 malloc
都可能失败,您应该检查一下,例如与
double *a1 = (double*)malloc(n * sizeof(double));
if (!a1) { perror("malloc a1"); exit (EXIT_FAILURE); };
假设您需要一些 C 代码。并且 malloc
可以 失败,例如当内核无法提供更多虚拟内存时,例如因为 mmap(2) failed, some limits have been reached (see getrlimit(2)...), swap space has been exhausted (with memory overcommit being disabled), etc.... Read about paging & page cache, and the man pages of malloc(3),特别是它的 NOTES 部分....顺便说一句,您的计算机有 finite 资源,所以它们可能会溢出。在便宜的笔记本电脑上,您将无法在 2015 年成功 malloc
10 TB 的内存(并可靠地使用内存区域)。当然,对于 n = 100000
,malloc
将 通常成功。
在实践中,如果您要求 大量 内存(千兆字节),malloc
可能会失败,但某些操作系统有 memory overcommitment(我个人不喜欢这个功能并在我的 Linux 系统上禁用)并给你一些指导,即使没有足够的 space 用于巨大的内存区域
万一n * sizeof(double)
溢出size_t
,灾难就会发生。
非 ALLOCATE_SEPARATE
要求 malloc(n * sizeof(double) * 4)
并且可能会溢出 n
的较小值(在实践中仍然很大)。 * 4
是必需的,因为我们要求足够的 space 来容纳四个不同的非 aliasing pointers 和它们的非重叠内存区域。
Is the second method in else block allocating in a contiguous manner?
当然可以(正如我所说,对于较小的 n
值可能会溢出或失败,例如,当 n * sizeof(double) * 4
即 n * 32
在 32 位 Linux(即 Android)平板电脑大于 3 GB,甚至可能是 1 GB。
实际上,您应该使用 C++11 containers 和代码:
#include <vector>
int main(){
const int n = 100000;
std::vector<double> vec(n);
vector 的数据将位于堆中,vec
的析构函数将释放它。
当然heap data is allocated in the address space of the virtual memory of your process (on Linux, probably using the mmap(2) -or sometimes sbrk
- syscall).
在这个回答中:
此人用两种方式在 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中的第二种方法是连续分配块吗?
(我专注于 Linux 观点;根据您的 operating system and/or 编译器实现进行调整)
您问题中的代码具有类似 C 语言的外观和感觉。正版 C++ 将使用 new
,即在非 ALLOCATE_SEPARATE
情况下类似于
double *a1 = new double[4*n];
double *b1 = a1 + n;
如果内存分配失败,您将得到一个 std::bad_alloc 异常。
What is the difference between the two ways of allocation?
ALLOCATE_SEPARATE
案例正在对 malloc
进行四次调用。请注意:
每个人
malloc
都可能失败,您应该检查一下,例如与double *a1 = (double*)malloc(n * sizeof(double)); if (!a1) { perror("malloc a1"); exit (EXIT_FAILURE); };
假设您需要一些 C 代码。并且
malloc
可以 失败,例如当内核无法提供更多虚拟内存时,例如因为 mmap(2) failed, some limits have been reached (see getrlimit(2)...), swap space has been exhausted (with memory overcommit being disabled), etc.... Read about paging & page cache, and the man pages of malloc(3),特别是它的 NOTES 部分....顺便说一句,您的计算机有 finite 资源,所以它们可能会溢出。在便宜的笔记本电脑上,您将无法在 2015 年成功malloc
10 TB 的内存(并可靠地使用内存区域)。当然,对于n = 100000
,malloc
将 通常成功。在实践中,如果您要求 大量 内存(千兆字节),
malloc
可能会失败,但某些操作系统有 memory overcommitment(我个人不喜欢这个功能并在我的 Linux 系统上禁用)并给你一些指导,即使没有足够的 space 用于巨大的内存区域万一
n * sizeof(double)
溢出size_t
,灾难就会发生。
非 ALLOCATE_SEPARATE
要求 malloc(n * sizeof(double) * 4)
并且可能会溢出 n
的较小值(在实践中仍然很大)。 * 4
是必需的,因为我们要求足够的 space 来容纳四个不同的非 aliasing pointers 和它们的非重叠内存区域。
Is the second method in else block allocating in a contiguous manner?
当然可以(正如我所说,对于较小的 n
值可能会溢出或失败,例如,当 n * sizeof(double) * 4
即 n * 32
在 32 位 Linux(即 Android)平板电脑大于 3 GB,甚至可能是 1 GB。
实际上,您应该使用 C++11 containers 和代码:
#include <vector>
int main(){
const int n = 100000;
std::vector<double> vec(n);
vector 的数据将位于堆中,vec
的析构函数将释放它。
当然heap data is allocated in the address space of the virtual memory of your process (on Linux, probably using the mmap(2) -or sometimes sbrk
- syscall).