这是我的代码:
#define MSK 0x0F
#define UNT 1
#define N 3000000000
unsigned char aln[1+N];
unsigned char pileup[1+N];
void set(unsigned long i)
{
if ((aln[i] & MSK) != MSK ) {
aln[i] += UNT;
}
}
int main(void) {}
Run Code Online (Sandbox Code Playgroud)
当我尝试编译它时,编译器抱怨如下:
tmp/ccJ4IgSa.o: In function `set':
bitmacs.c:(.text+0xf): relocation truncated to fit: R_X86_64_32S against symbol `aln' defined in COMMON \
section in /tmp/ccJ4IgSa.o
bitmacs.c:(.text+0x29): relocation truncated to fit: R_X86_64_32S against symbol `aln' defined in COMMON\
section in /tmp/ccJ4IgSa.o
bitmacs.c:(.text+0x32): relocation truncated to fit: R_X86_64_32S against symbol `aln' defined in COMMON\
section in /tmp/ccJ4IgSa.o
Run Code Online (Sandbox Code Playgroud)
我认为原因可能N是太大,因为它可以成功编译,如果我将N改为2000000000.但我需要3000000000作为N的值..
有人有这个想法吗?
根据您的原始问题:使用整数文字后缀UL(或类似)强制存储类型为N:
#define N 3000000000UL
Run Code Online (Sandbox Code Playgroud)
然而,(根据您对HLundvall的答案的评论),relocation truncated to fit错误显然不是由于这个 - 它可能(正如Mystical和Matt Lacey所说)只是太大而不适合细分市场.
顺便说一句,如果你问一个单独的问题,解释你想用你的巨大阵列完成什么,有人可能会建议一个更好的解决方案(更有可能适合内存)
例如:
忽略数字文字不正确类型的"形式"问题(请参阅其他答案以获得正确的语法),这里的关键点是分配3 GB静态/全局数组是一个非常糟糕的主意.
static大多数平台上的全局1变量直接从可执行映像映射,这意味着您的可执行文件必须大到3 GB,即使对于当前标准来说也是如此.即使在某些平台上可能会解除此限制(请参阅注释),您也无法控制如何处理分配失败.
最重要的是,全局变量不适用于这么大的东西,并且您可能会发现链接器(例如您找到的)和加载器强加的任意限制的问题.相反,你应该分配什么,这比在堆上几KB更大,使用malloc,new或某些特定于平台的功能,优雅地处理在运行时可能出现的故障.
但是,请记住,对于在几乎任何32位操作系统下运行的应用程序,不可能根据您的要求获得3 GB的连续内存,并且完全不可能获得多个这些数组(=超过4 GB的数据)连续的内存)而不依赖于特定于平台的技巧(例如,在给定时刻仅映射内存中数组的特定部分).
此外,您确定自从程序开始运行以来确实需要所有连续的内存吗?是不是有一些更好的数据结构/算法可以避免分配所有内存?