首先,你没有说你在哪个架构中尝试这种方法。其次,你没有说你使用的是什么操作系统。你只说你在尝试malloc(3)一个十亿的数组ints。
三思而后行:包含 1 000 0000 001 int 元素的单个数组的大小为 4 000 000 004。如果您尝试在 32 位架构中处理此问题,则您要求系统仅为您的阵列分配完整的虚拟内存空间(即 4Gb)。很可能你有一个非常硬的限制,阻碍你分配这么多的内存。
在 64 位架构中,您有足够的地址来处理它,但同样,您的操作系统可能会拒绝创建这种大小(或您的系统可以处理的虚拟内存量)的单个连续映射。最有可能的是,您将无法获得该内存。我看到您正在 Windows 中运行它(通过您用于文件名的路径)所以很可能您甚至无法检查每个进程可以处理多少内存。
我已经在 FreeBSD 64 位架构中测试了您的程序,在该架构中我有以下限制(我不得不承认我已经对它们进行了一些调整以处理您的用户帐户问题,因为多用户系统中的普通用户是默认情况下从未授予此类限制):
$ ulimit -a
number of pseudoterminals (-P) unlimited
socket buffer size (bytes, -b) unlimited
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) 33554432
file size (blocks, -f) unlimited
max kqueues (-k) unlimited
max locked memory (kbytes, -l) unlimited
max memory size (kbytes, -m) unlimited
open files (-n) 230121
pipe size (512 bytes, -p) 1
stack size (kbytes, -s) 524288
cpu time (seconds, -t) unlimited
max user processes (-u) 12042
virtual memory (kbytes, -v) unlimited
swap size (kbytes, -w) unlimited
(如您所见,我的最大数据段大小限制为 33Gb,因此,如果我要求 100 亿个元素的数组,我失败了,需要说这个限制是由内核强加的,我不能提高它——即使是根)
- 当我这样做时,我得到了一个
SIGSEGV,因为fopen(3) 返回的文件指针给了NULL(文件不存在,另一件事你没有在你的程序中检查)所以程序是fscanf(3) 呼叫中止。 注意:您需要检查调用的返回值是否有错误。
- 在那之后,我完全能够毫无问题地运行(并且确实分配了十亿 -- 加一个 -- 元素数组)。 FreeBSD 程序从头到尾在 0.001 秒内运行,因为它不必在一个块中分配所有内存(实际上,它不必全部分配,因为您只使用数组的前 126 个元素,所以实际上,您只会分配一页这样的内存,即 504 字节的内存。
$ pru
*****************************************
THIS WAS FRIEND CIRCLE QUERIES
*****************************************
numberOfHandshakings: 99885
persons[0]= 0
persons[1]= 0
persons[2]= 0
[...]
persons[123]= 0
persons[124]= 0
persons[125]= 0
persons[126]= 0
然后我把最大虚拟内存空间固定为4Gb,重复测试:
$ pru
*****************************************
THIS WAS FRIEND CIRCLE QUERIES
*****************************************
numberOfHandshakings: 99885
malloc failed: Cannot allocate memory
这一次,ulimit -a 的结果是:
$ ulimit -a
number of pseudoterminals (-P) unlimited
[... same as before ]
max user processes (-u) 12042
virtual memory (kbytes, -v) 4194304 <<<<<< 4Gb virtual memory.
swap size (kbytes, -w) unlimited
您的程序,经过我对其进行的修改以能够处理对fopen() 和malloc() 的调用返回的错误是:
#include <ctype.h>
#include <errno.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define population 1000000000
int numberOfHandshaking;
int main(int argc, char **argv)
{
printf("*****************************************\n");
printf(" THIS WAS FRIEND CIRCLE QUERIES\n");
printf("*****************************************\n\n");
FILE *fPointer;
fPointer =
fopen("Ass13in.txt", /* I changed this, my apologies */
"r");
if (fPointer == NULL) {
printf("couldn't open file: %s\n", strerror(errno));
exit(1);
}
fscanf(fPointer, "%d", &numberOfHandshaking); // Reads the first line
printf("numberOfHandshakings: %d\n", numberOfHandshaking);
int *persons = malloc((population+1) * sizeof(int));
if (persons == NULL) {
printf("malloc failed: %s\n", strerror(errno));
exit(1);
}
for (int i=0; i<127; i++){
printf("persons[%d]= %d \n", i, persons[i]);
}
printf("\n\n\n");
return 0;
}
它运行良好! :)
注意:
在您的程序中,您不需要使用 #include 文件。它们是:
#include <ctype.h>
#include <math.h>
#include <time.h>