Блог пользователя foundnt_Alice

Автор foundnt_Alice, история, 7 месяцев назад, По-английски

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!

  • Проголосовать: нравится
  • +6
  • Проголосовать: не нравится

»
7 месяцев назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

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

  • »
    »
    7 месяцев назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

    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.

    • »
      »
      »
      7 месяцев назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

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

      • »
        »
        »
        »
        7 месяцев назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        so that's how struct works? Tks!

        • »
          »
          »
          »
          »
          7 месяцев назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится

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

          • »
            »
            »
            »
            »
            »
            7 месяцев назад, # ^ |
              Проголосовать: нравится 0 Проголосовать: не нравится

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

          • »
            »
            »
            »
            »
            »
            7 месяцев назад, # ^ |
              Проголосовать: нравится 0 Проголосовать: не нравится

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

            • »
              »
              »
              »
              »
              »
              »
              7 месяцев назад, # ^ |
                Проголосовать: нравится 0 Проголосовать: не нравится

              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.

»
7 месяцев назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

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];
»
7 месяцев назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

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