calloc 2 gb的内存类型为' char'但成功的短期'

时间:2014-09-04 16:34:27

标签: c memory malloc calloc

我试过calloc一个2GByte的表。以下代码失败

#define MAX_FILEID      131072                  // 17 bits 131K file IDs
#define MAX_OFFSET      8192                    // offset loctions (refLoc - Loc)
#define MATCH_TAB_SIZE  (MAX_OFFSET*MAX_FILEID)

matchTab = (unsigned char*) calloc(MATCH_TAB_SIZE*2, sizeof(unsigned char));
if ( matchTab==NULL)
{
    fprintf(stderr, "calloc %f Mbyte failed for matchTab \n", MATCH_TAB_SIZE*sizeof(unsigned char)/(1024*1024.0) );
    return;
}
else
{
    fprintf(stdout, "assigned %f Mbyte \n", MATCH_TAB_SIZE*sizeof(unsigned char)/(1024*1024.0) );
}

但是,如果我将calloc行替换为

matchTab = (unsigned short*) calloc(MATCH_TAB_SIZE, sizeof(unsigned short));

成功了。

我想知道为什么。我的机器是一个64位的Linux,至少有80 GB的内存。

1 个答案:

答案 0 :(得分:1)

8192 * 131072 * 2 = 2 31

2 31 >您的实现中INT_MAX,因此上面的表达式溢出。它的结果是未定义的。

使用足够大的类型的文字,例如unsigned int

#define MAX_FILEID      131072U                  // 17 bits 131K file IDs
#define MAX_OFFSET      8192U                    // offset loctions (refLoc - Loc)
#define MATCH_TAB_SIZE  (MAX_OFFSET*MAX_FILEID)

matchTab = calloc(MATCH_TAB_SIZE*2U, sizeof(unsigned char));

或者,在数字较小时将数字转换为size_t

matchTab = calloc(((size_t)MATCH_TAB_SIZE)*2, sizeof(unsigned char));

注意,不要投射calloc和朋友的结果。 sizeof(unsigned char)始终为1,因此您可以根据需要使用1