malloc有时会失败。或者有时会失败

时间:2014-03-24 02:09:01

标签: c linux memory-management malloc

所以我有一个测试程序,它将大量数据读入缓冲区并进行mallocs 因此缓冲。然而,malloc在巨大的尺寸上失败了。

有没有办法解决这个问题?

感谢任何回复

设备/ dev / sdc是一个2TB磁盘。

这里有2个编译代码:

#define          _FILE_OFFSET_BITS                            64     
#define          BLKGETSIZE64                                _IOR(0x12,114,size_t)    
#define          _POSIX_C_SOURCE                             200809L

#include <stdio.h>    
#include <inttypes.h>    
#include <stdlib.h>    
#include <fcntl.h>    
#include <unistd.h>

int readdata(int fp,uint64_t seekpoint, uint64_t seekwidth) {

    int16_t  *buf;

    buf=(int16_t *)malloc(seekwidth*sizeof(int16_t)+1);
    if (buf==0) {
      printf("ERROR malloc(%"PRIu64")\n",seekwidth*(sizeof(int16_t)));
      return 3;
    }

    if (pread(fp,buf,seekwidth,seekpoint)==seekwidth) {
        printf("SUCCES READING AT: %"PRIu64"| WITH READ WIDTH: %"PRIu64"\n",seekpoint,seekwidth);
        free(buf);
        return 1;
    } else {
        printf("ERROR READING AT: %"PRIu64"| WITH READ WIDTH: %"PRIu64"\n",seekpoint,seekwidth);
        free(buf);
        return 2;
    }

}



int main() {
    uint64_t    readwith,
                offset;
    int         fp=open("/dev/sdc",O_RDWR);

    readwith=10000;   offset=0;
    readdata(fp,offset,readwith);
    readwith=100000;   offset=0;
    readdata(fp,offset,readwith);
    readwith=1000000;   offset=0;
    readdata(fp,offset,readwith);
    readwith=10000000;   offset=0;
    readdata(fp,offset,readwith);
    readwith=100000000;   offset=0;
    readdata(fp,offset,readwith);
    readwith=1000000000;   offset=0;
    readdata(fp,offset,readwith);
    readwith=10000000000;   offset=0;
    readdata(fp,offset,readwith);
    close(fp);

}

我系统上的输出是:

SUCCES READING AT: 0| WITH READ WIDTH: 10000
SUCCES READING AT: 0| WITH READ WIDTH: 100000
SUCCES READING AT: 0| WITH READ WIDTH: 1000000
SUCCES READING AT: 0| WITH READ WIDTH: 10000000
SUCCES READING AT: 0| WITH READ WIDTH: 100000000
SUCCES READING AT: 0| WITH READ WIDTH: 1000000000
ERROR READING AT: 0| WITH READ WIDTH: 10000000000
ERROR READING AT: 0| WITH READ WIDTH: 100000000000
ERROR READING AT: 0| WITH READ WIDTH: 1000000000000
ERROR READING AT: 0| WITH READ WIDTH: 10000000000000
ERROR READING AT: 0| WITH READ WIDTH: 100000000000000
ERROR READING AT: 0| WITH READ WIDTH: 1000000000000000

有时候

ERROR malloc(2000000000)
ERROR READING AT: 0| WITH READ WIDTH: 10000000000

3 个答案:

答案 0 :(得分:2)

好吧,我会说你不能分配大小为10000000000的内存,因为那是9536 MiB,我想你没有那么多内存。

您可以考虑使用STXXL

  

STXXL的核心是C ++标准模板的实现   用于外部存储器(核外)计算的库STL,i。即,   STXXL实现了可以处理巨大的容器和算法   仅适合磁盘的大量数据。

答案 1 :(得分:1)

Doug lea malloc(dlmalloc)关于块的最小和最大尺寸

  

如果n为零,则malloc返回最小大小的块。 (最小尺寸   在大多数32位系统上是16字节,在64位系统上是32字节。)   请注意,size_t是无符号类型,因此使用参数调用   如果签名被解释为巨大的请求将是负面的   空间的数量,往往会失败。 支持的最大值   n的系统不同,**但在所有情况下都小于最大值   size_t 的可表示值。

最大块大小可以是(2 ^ 31),大约 2147483648

所以在你的情况下,最后一次成功的malloc调用是1000000000 * 2大于上面的最大值,因此malloc返回NULL。

答案 2 :(得分:1)

如果您想对整个磁盘或大文件上的数据执行某些操作,您可能希望改为使用mmap(2)

从手册页:

  

mmap()在虚拟地址空间中创建一个新映射   呼叫过程。

int fd = open("/dev/sdc", O_RDONLY);
unsigned char *data = mmap(NULL, length, PROT_READ, MAP_SHARED, fd, 0);

如果您希望能够写入磁盘,事情变得更加棘手和危险,但这也是可能的(有关详细信息,请参阅mmap(2)手册页。)