malloc() 不为大块内存分配内存

malloc() not allocate memory for large blocks of memory

我正在尝试制作一个分配内存然后用随机数据填充分配的内存的程序,在这种情况下 A 并多次执行此操作然后打印填充 100 所需的时间mb 以毫秒为单位。 该程序应该每次分配 100 mb 的倍数。该程序应该最多执行此操作 9000 mb。我这样做的原因是为了演示 OS 在 运行 没有可用内存并使用交换 space 时的行为。但是我这样做有问题。

当我 运行 程序时,它的行为就像它应该做的那样,直到我达到 2100 mb 然后它停止分配内存,一段时间后错误处理程序启动并退出程序,因为 malloc() returns NULL.

这是代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <assert.h>
#include <unistd.h>
#define KILO    1024
#define MEGA (KILO*KILO)
#define INCREMENT 100

int diffTime(struct timeval * startTime, struct timeval * endTime) {
    return ((endTime->tv_sec - startTime->tv_sec)*1000 + (endTime->tv_usec- startTime->tv_usec)/1000);
}

int createBigDatablock(long int storlek) {
    char *arr = (char*) malloc(storlek*MEGA);
    if (arr==NULL){
        printf("Error: not allocating memory");
        exit (-1);  
    }
    for(int i = 0;i<storlek*MEGA;i++){
        arr[i] = 'A';
    }
    fflush(stdin);
    getchar();
    free(arr);
    return 0;
}



int main(void) {
    long int i;
    struct timeval startT, endT;
    // struct timezone tzp;
    for(i=INCREMENT;i<=9000;i=i+INCREMENT){
        gettimeofday(&startT, NULL); //&tzp); /* hämta starttid */
        createBigDatablock(i);
        gettimeofday(&endT, NULL);//&tzp); /* hämta sluttid */
        printf("Datablock  %ld MB took %d msec\n",i, diffTime(&startT,&endT));
    }
    return 0;
}

我已经尝试 运行 在装有 debian 8、4 GB 内存和 570 MB 交换空间的虚拟机上执行此操作。内存永远不会被完全填满,交换 space 也永远不会被触及。如果有人能帮我解决这个问题,我将不胜感激

您可能有一个 32 位系统,您不能为每个进程分配超过 2 GB 的内存。

如果malloc returns NULL,表示无法分配内存。

所以你的程序的行为是正常的。

另一种可能是它根本找不到足够大的空闲连续内存块。

交换space从未被触及的原因可能是因为您的虚拟机有4GB内存,所以总是有足够的空闲内存可用。 如果你想使用 swap space,你可以尝试分配很多更小的内存块,例如 40 乘以 100Mb;那么你能够分配的内存总量也可能高于2100Mb。

我偶然发现了这段代码并在 Fedora 34 X86_64 系统上编译了它。它会在将 A 写入内存位置的循环中的数据块 2100 处发生段错误。我将 i 更改为 long int i 并且我的系统几乎停止运行但在另一个终端上观看免费显示它正在填充交换。我还没有完全测试它,但它似乎在工作。这里有两个 i 变量,也许它们被认为是分开的。

for(int i = 0;i<storlek*MEGA;i++){
    arr[i] = 'A';


for(long int i = 0;i<storlek*MEGA;i++){
    arr[i] = 'A';