在线提交的编译文件太大[202493852字节]错误

Compiled file is too large [202493852 bytes] error from on-line submission

本文关键字:202493852字节 错误 提交 编译 文件 在线      更新时间:2024-09-29

在使用2-D数组时,我尝试使用一个静态数组,将-1分配给它的第一个元素:

int dp[5001][5001] = {-1};   //setting dp[0][0] to -1
int calc(int i, int j){
//Some operations are happening here which utilize dp array.
}
int main(){
cout << calc(0,0);
}

当我在线提交此代码片段作为解决方案时,我得到了Can't compile file: Compiled file is too large [202493852 bytes]

但是,当我尝试在main((中设置dp值时

int dp[5001][5001];
int calc(int i, int j){
//Some operations are happening here which utilize dp array.
}
int main(){
dp[0][0] = -1;
cout << calc(0,0);
}

上面的代码段已成功接受并编译。

有人能解释为什么会发生这种情况吗?

当您使用初始化器(如(声明静态数组

int dp[5001][5001] = {-1};

整个数组被放入可执行文件的数据部分。它的大小是编译器的(5001×5001=2501001(×sizeof(int)。如果是sizeof(int)==8,则数组的大小(以字节为单位(200080008接近您引用的限制。最终,二进制文件中还有其他内容。

另一方面,第二个示例中没有初始化器的数组

int dp[5001][5001];

未在可执行文件中分配任何数据空间;相反,只有一个小记录告诉加载程序在启动时在进程的地址空间中分配一个零初始化的内存块。

此优化不是强制性的,但ELF和Windows PE二进制文件都使用它。初始化的数据段通常称为.data,而未初始化的.bss


一个展示概念的小型实践实验

// Save me as bss.cc
int without_initializer[10000][10000];      // 100 million elements.
int with_initializer[1000][1000] = { 42 };  // 1 million elements.
/*
Run and see:
$ c++ -c -o bss.o bss.cc
$ ls -l bss.o
-rw-r--r-- 1 kkm kkm 4001008 2021-05-18 06:00:19 bss.o
$ objdump -h bss.o
bss.o:     file format elf64-x86-64
Sections:
Idx Name          Size      VMA               LMA               File off  Algn
0 .text         00000000  0000000000000000  0000000000000000  00000040  2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data         003d0900  0000000000000000  0000000000000000  00000040  2**5
CONTENTS, ALLOC, LOAD, DATA
2 .bss          17d78400  0000000000000000  0000000000000000  003d0940  2**5
ALLOC
3 .comment      0000001d  0000000000000000  0000000000000000  003d0940  2**0
CONTENTS, READONLY
$ rm bss.cc bss.o
*/

.data部分的大小为0x3d0900=4000000字节。显然,这个编译器的sizeof(int)是4。它还有LOAD标志,这意味着它必须从文件中加载,链接的答案中对此有很好的解释。

ls(1(显示,对象文件的大小只比相同的4000000字节大一点,头文件和小的.comment部分占用了一点额外的空间,可能会识别编译器(如果你很好奇,objdump(1(可以转储其内容(。

.bss部分的大小为0x17d78400=400000000,正好等于sizeof(without_initializer)。它有ALLOC标志来告诉加载程序它必须在进程的地址空间中,但没有LOAD标志,这意味着没有什么可以从文件中加载的。

您可能会注意到,.bss节在文件中正好占用0个字节:它的偏移量和以下.comment节的偏移量都是0x003d0940。

使用Linux命令及其ELF格式。在Windows上,如果您手边有Visual Studio,请在Native Tools命令提示符下使用cl /c bss.cc,然后使用dumpbin /headers bss.obj