Rating changes for last rounds are temporarily rolled back. They will be returned soon. ×

foundnt_Alice's blog

By foundnt_Alice, history, 5 months ago, In English

Hi all!

Recently, I tried to implement a HLD struct. However, my local computer shows Segmentation Fault verdict as soon as I set the constraint of N to 1e5, the online judge shows TLE verdict btw. Small constraint on N works just fine. Here is the code:

Segmentation Fault Code

So, I tried to rewrite the same code without using struct. This time my local computer ran smoothly and the online judge showed AC verdict.

The AC code:

Could someone plz explain why's there a difference verdict in my codes? Where did I get it wrong? I much appreciate it!

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

»
5 months ago, # |
Rev. 2   Vote: I like it 0 Vote: I do not like it

Probably, stack overflow (you allocated a variable of your struct on the stack, and the size of the variable is about 12Mb).

  • »
    »
    5 months ago, # ^ |
    Rev. 2   Vote: I like it 0 Vote: I do not like it

    both codes have the same constraint of N. So if the struct version got stack overflow, should the other version got the same verdict? I don't really get it.

    • »
      »
      »
      5 months ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      In the first version you use the stack for the local variable h, in the second version the memory is allocated statically.

      • »
        »
        »
        »
        5 months ago, # ^ |
          Vote: I like it 0 Vote: I do not like it

        so that's how struct works? Tks!

        • »
          »
          »
          »
          »
          5 months ago, # ^ |
            Vote: I like it 0 Vote: I do not like it

          You can use vectors instead of arrays in the struct and your first version will work without such issues.

          • »
            »
            »
            »
            »
            »
            5 months ago, # ^ |
              Vote: I like it 0 Vote: I do not like it

            I just figured out the problem. The first version of code works OK when I declare the struct globally. Damn, I'm clueless

          • »
            »
            »
            »
            »
            »
            5 months ago, # ^ |
              Vote: I like it 0 Vote: I do not like it

            Similarly, the AC code got Segmentation Fault if I declare the struct locally

            • »
              »
              »
              »
              »
              »
              »
              5 months ago, # ^ |
                Vote: I like it 0 Vote: I do not like it

              It does not matter whether you use struct or just define local variable buffer as char buffer[sizeof(HLD)];. If the stack size is less than sizeof(HLD), you get stack overflow in any case.

              • »
                »
                »
                »
                »
                »
                »
                »
                5 months ago, # ^ |
                  Vote: I like it 0 Vote: I do not like it

                That's why it's so weird that the code gets segmentation fault if I declare struct locally (N = 1e5) and run smoothly when I declare struct globally. I just don't get it

                • »
                  »
                  »
                  »
                  »
                  »
                  »
                  »
                  »
                  5 months ago, # ^ |
                    Vote: I like it 0 Vote: I do not like it

                  What do you expect if you have only 8Mb for local variables but one of your local variables is of bigger size? When you declare variables in the global scope, the stack is not used for them.

              • »
                »
                »
                »
                »
                »
                »
                »
                5 months ago, # ^ |
                  Vote: I like it 0 Vote: I do not like it

                ![ ](1)

              • »
                »
                »
                »
                »
                »
                »
                »
                5 months ago, # ^ |
                  Vote: I like it 0 Vote: I do not like it
»
5 months ago, # |
Rev. 2   Vote: I like it 0 Vote: I do not like it

You can try replacing HLD<int> h; by auto& h = *(new HLD<int>{}); — this will prevent it from being allocated on the stack.

If you care about memory leaks, here's an ugly hack:

std::vector<HLD<int>> v(1);
auto& h = v[0];
»
5 months ago, # |
  Vote: I like it 0 Vote: I do not like it

I believe this is because of stack vs heap allocation, the stack is a rather small section of the memory that (for development purposes) is mostly just meant to hold pointers to real data. (Eg. Your stack might be 8-16Mb and your heap might be the rest of your memory)

When you create(instantiate) a struct inside a function, the memory is allocated on the stack. In the case above, the struct holds a lot of arrays (arrays declared like this are also allocated in the same place as your struct) and so you overflow the amount of memory your stack actually has. (stack overflow)

In the global case however, all your variables are, well, global. And by default all global variables are allocated on the heap, so you don't get any problems

This is why when you create your struct globally it works, because the struct and all the arrays you create move to the heap.

If you ever encounter something like this these are things you can try
1. use vector instead of int arr[n]: internally vector actually uses pointers to store the data, and all the data is allocated on the heap
2. Use pointers instead of int arr[n]: Same logic as vector but DIY. This comes with the extra headache of having to free the memory yourself so I wouldn't do it.
3. Declare your struct globally: as you did
4. Use pointer to struct: same logic as pointer to arrays for the data, but you make (and are responsible for freeing) just the one pointer