我需要在我的C程序中分配超过4GB的内存(在Windows上运行 - 64位)
显然只使用malloc
并不能解决问题。
我已经以这种方式阅读了之前的一些帖子,似乎VirtualAlloc
可以解决我的问题。
我试图使用它,我不明白与此功能相关的所有参数。
我想我需要准确定义应该分配内存的地址,但我不知道该怎么做
是否有关于它的简单信息,或者我可以使用的简单示例?
我也不需要在一个块中分配所有内容,因此可能更容易。还可以接受任何分配超过4GB内存的替代方法。
感谢。
答案 0 :(得分:6)
与您的陈述相反,malloc()
将解决问题,假设您正在使用可以生成64位可执行文件的实现(包括编译器和库),并将其配置为执行此操作(即构建一个64位目标)。一些工具链能够构建64位目标,但默认情况下(例如,在关联的IDE中使用)将只生成32位可执行文件。
如果要构建32位目标(即生成32位可执行文件),那么,是的,malloc()
将限制为4GB。可以在64位系统上执行32位可执行文件(假设操作系统允许这样做)。但是,在这种情况下,程序对malloc()
的使用仍将限制为4GB。
这意味着您需要确保拥有可以构建64位程序的编译器并使用它来构建64位目标。
当然,您应该问的另一个问题是,您是否真的需要在一个块中分配超过4GB的内容。虽然在某些情况下这是合适的,但通常情况下,需要这样做的程序是设计不良或懒惰的标志。
答案 1 :(得分:5)
显然只使用malloc并不能解决问题。
为什么呢? size_t
应该足够大,以涵盖您的计划可以访问的所有地址空间,malloc
需要size_t
,并且没有标准的理由说明为什么它不应该工作。
遗憾的是我现在不能在Windows机器上尝试这个,但是在Linux机器上这个程序工作得很好(表明C中没有任何限制会阻止你这样做):
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int
main(int argc, char **argv)
{
size_t sz = 40000000000;
char *a = malloc(sz);
memset(a, 'a', sz);
printf("%.4s", &a[sz-5]);
return 0;
}
我分配40GB,用字母填写#&a;&#39; a&#39;然后访问它只是为了看到事情有效。他们这样做。 (警告:不要在没有这么多内存的机器上运行这个程序,当你过度使用内存时,系统可能会非常不满意。)
这个程序对你有用吗(尺寸调整到你的硬件可以做什么,显然)?如果是,那么您可能会遇到尺寸原型或数据类型的问题,而不是malloc
的问题。
答案 2 :(得分:1)
在Windows中分配超过4GB内存的最简单方法是编译为64位程序。如果您使用Visual Studio,有两种方法可以做到这一点。
在初始屏幕上,在&#34; debug&#34;旁边的顶部下拉列表中有一个下拉列表,用于指定程序要编译的模式。默认值为&#34; x86&#34;。单击下拉列表并选择&#34; x64&#34;。
第二种方法是单击项目的属性。在下一个屏幕上,&#34;平台&#34;旁边是配置管理器按钮。单击它,将显示Configuration Manager屏幕。在&#34; Active解决方案平台&#34;单击下拉列表并选择&#34; x64&#34;。
然后正常malloc
将使用超过4GB。
这是使用Visual Studio 2015.我假设您可以在其他版本的VS中执行类似操作。
答案 3 :(得分:1)
假设1)size_t/SIZE_MAX
小于可用内存2)并且OP需要执行单大分配:
测试您的系统calloc()
。
根据实现情况,calloc()
可以分配超过SIZE_MAX
个字节。以下将分配4*SIZE_MAX
个字节。
uint32_t *p;
size_t nmemb = SIZE_MAX;
p = calloc(nmemb, sizeof *p);
asset(p);
for (size_t i = 0; i < nmemb; i++) {
p[i] = ...
}
free(p);
当size_t
为16位且可用内存比此大许多倍时,我使用过这种类型的代码。
OTOH,某些calloc(size_t nmemb, size_t size)
将不允许在哪里分配
(nmemb * size) > SIZE_MAX
。 YMMV