在C中分配超过4GB的内存

时间:2016-06-23 09:56:41

标签: c

我需要在我的C程序中分配超过4GB的内存(在Windows上运行 - 64位) 显然只使用malloc并不能解决问题。

我已经以这种方式阅读了之前的一些帖子,似乎VirtualAlloc可以解决我的问题。
我试图使用它,我不明白与此功能相关的所有参数。 我想我需要准确定义应该分配内存的地址,但我不知道该怎么做 是否有关于它的简单信息,或者我可以使用的简单示例?

我也不需要在一个块中分配所有内容,因此可能更容易。还可以接受任何分配超过4GB内存的替代方法。

感谢。

4 个答案:

答案 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