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

Автор shashankagrawal, история, 4 года назад, По-английски

We can change stack size in linux temporarily by using the command ulimit -s new_value, But is there any way to change stack size permanently, or Can we do something within C++ code, so it will change stack size by itself?

I tried changing this, but It didn't work. I faced this issue in hackercup qualification round D2, terminal gave segfault, and later I came to know about the low value of default stack size in linux.

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

»
4 года назад, # |
  Проголосовать: нравится +21 Проголосовать: не нравится

After altering limits.conf, have you tried logging off and logging back into your account? I believe the changes won't come into effect unless you do this.

»
4 года назад, # |
  Проголосовать: нравится +18 Проголосовать: не нравится

I feel u bro, same thing happened to me, but even worse I was on Windows using VS code, spent half an hour trying to find what's the problem :( then after a long search edited my compilation flags as shown here

  • »
    »
    4 года назад, # ^ |
      Проголосовать: нравится +3 Проголосовать: не нравится

    Yeah, sad!

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

    Given link work only for codeblocks. Is there any way/command-flag which i can use in VScode for this purpose?

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

      I don't use codeblocks, just edited my compilation flags, whatever IDE u might be using, search in your setting how to edit your compilation flags and it should work fine

»
4 года назад, # |
Rev. 2   Проголосовать: нравится +25 Проголосовать: не нравится

Just typing ulimit -s into terminal should give you the default stack size. For me, it's 8192, i.e. 8 MiB.

To change the stack size in the code, you can use getrlimit() and setrlimit() system calls:

#include <sys/resource.h>

int main() {
    rlimit rlim;
    if (getrlimit(RLIMIT_STACK, &rlim)) return 1;
    rlim.rlim_cur = rlim.rlim_max;
    // You can set the fixed value instead of max value, e.g. rlim.rlim_cur = 1024 * 1024 * 1024
    // will set your stack size to 1 GiB
    if (setrlimit(RLIMIT_STACK, &rlim)) return 2;

    // Your code here...

    return 0;
}

Note that this example will work only for UNIX-like systems, so it's better to disable this code (using #ifdef, for example) when submitting to an online judge.

  • »
    »
    4 года назад, # ^ |
      Проголосовать: нравится +10 Проголосовать: не нравится

    Thank you very much!

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

    Is it a good idea to have stack size something as big as 1 gb when default size is like 8MB?

    Does it have any side-effects?

    • »
      »
      »
      4 года назад, # ^ |
        Проголосовать: нравится +31 Проголосовать: не нравится

      If you have infinite recursion, then your program crashes much later, and possibly after consuming all system memory.

      Suggestion: Leave it as default and raise only when needed in individual cases.

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

        Does the same occur on increasing it not to rlim_max but to 1 Gb instead ?

        P.S — just curious because i added it in my snippet and made limit to 1 Gb and it should return segmentation fault after crossing the 1 Gb limit but I'm not in mood to try after reading your Comment.

        • »
          »
          »
          »
          »
          4 года назад, # ^ |
            Проголосовать: нравится +5 Проголосовать: не нравится

          If you increase it to 1 GiB, then the program will segfault if it tries to exceed this limit. If you always have 1 GiB of free memory while solving contests, everything should be fine.

          Also I noticed that I made a tiny mistake in the comment above, which is fixed now. setrlimit() takes stack size in bytes, so 1 GiB would be rlim.rlim_cur = 1024 * 1024 * 1024. If you added this code into your snippet, it's better to fix it.

      • »
        »
        »
        »
        4 года назад, # ^ |
          Проголосовать: нравится +8 Проголосовать: не нравится

        I use the following wrapper to run the solutions locally:

        bash -c 'ulimit -s 262144 && ulimit -v 2097152 && time "./%e"'
        

        ulimit -v is used to limit the amount of memory, so I won't go out of memory in case of infinite memory allocation.

»
4 года назад, # |
  Проголосовать: нравится +29 Проголосовать: не нравится

I failed D2 because of the exact same issue :(

»
3 года назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Maybe you can just add ulimit -s new_value to your .bashrc file?