我试过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的内存。
答案 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
。