roll_no_1's blog

By roll_no_1, 5 years ago, In English

This post elaborates on what is written in the title. So, it may not be relevant to many people. But if you get this kind of error someday on codeforces, this post may be helpful for you.

TL;DR: If you get this kind of an error, check to see if you are initializing a global array with a non-default value. If that's the case, move the piece of code doing the initialization inside the main function, or just replace the array with a vector.

A few days back, I was solving a problem with $$$N \le 10^6$$$. I thought of using lazy propagation to solve it. For this, I used my own template of lazy propagation. But, after coding the solution to the problem, I realized that the compilation of the source file was taking too much time on my laptop. So, I tried to use the custom invocation feature of codeforces. But amazingly, to my surprise, I got a compilation error like this:

Invocation failed [COMPILATION_ERROR]

Can't compile file:

Compiled file is too large [34412820 bytes], but maximal allowed size is 33554432 bytes.

Then, I remembered that once I tried using my lazy propagation template on some problem and got an error like this:

Invocation failed [COMPILATION_ERROR]

Can't compile file:

Compilation process timed out.

At that time, I got help from this comment by Riatre, according to which if we initialize a global array with some non-default value, the compiler will generate an initialized array, write it to the output binary file, which not only increases the size of the binary file but also increases the compilation time.

A workaround for this is to initialize the array in the main function.

I just thought it was a one-time thing and I managed to work it out by replacing arrays with vectors. But I got a similar error like that (the one in the title) again a few days back with my template for lazy propagation.

In my code, the part that was responsible for this looked something like this:

struct ans {
    int val = 1, lazy = -1;
};

which represents a node. And for the segment tree itself, I had a global array declaration like this:

ans st[N<<2];

This was the reason that the output binary file on my system was 32 MB in size.

A workaround to this is that I could have explicitly initialized the array values using std::fill or maybe using a loop. But I like default arguments, so this is what I did:

The following piece of code does exactly the same thing as the code above, but using this, the size of the output binary got reduced to 16.2 KB, which resulted in a faster compilation as well.

struct ans {
    int val, lazy;
    ans(int _val = 1, int _lazy = -1)
        :val(_val), lazy(_lazy){}
};

So, if you ever come across such an error, look out for global array initializations and work them out. Either move them in the main function or use vectors. In case you are using structs / classes with default values for the attributes, consider making a constructor and move the default values to the constructor.

Here are the 2 pieces of code if you want to try them out in custom invocation.

Code 1: Compilation Error on custom invocation.

Code 2: Compiles successfully on custom invocation.

P.S.: As both codes above do almost exactly the same thing, if you know the reason as to why in the first case the array gets written to the binary file but not in the second case or you have some relevant links regarding this thing, please provide them in the comments section.

  • Vote: I like it
  • +43
  • Vote: I do not like it

»
5 years ago, # |
  Vote: I like it +11 Vote: I do not like it

Using global variables is a bad pattern, it's totally fine that you get an error

  • »
    »
    5 years ago, # ^ |
      Vote: I like it +20 Vote: I do not like it

    Alright, but they do make coding easier and that's the reason many people use them in competitive coding.