0

I was trying to do a problem on HackerEarth, and I am getting Segmentation Faults for this for loop:

for (int index = 0; index < 18; index++){
    cout << arr_list[arr_index][index];
}

Even though I assigned values to arr_list[arr_index][index] in the loop right before (so I'm guessing the values are somehow not being saved, but I don't know how the values aren't being saved).

When I remove this for loop, I don't get any segfaults, and the cout information prints what's expected (the numbers I've inputted, with each digit twice for each cout inside the loop).

#include <iostream>
#include <string>

using namespace std;

void step(int arr_list[1000000][18], int cs, int N){
    /**
    int freq[100000] = {0};

    for (int i = 0; i < N; i++){
        int cur_arr[18];

        for (int index = 0; index < 18; index++){
            cur_arr[index] = arr_list[i][index]; 
        }

        if (cs == 4){
            freq[cur_arr[0]*100 + cur_arr[1] * 10 + cur_arr[2]] += 1;
        } else{
            freq[cur_arr[18 - cs*5] * 10000 + cur_arr[18 - cs*5 + 1] * 1000 + cur_arr[18 - cs*5 + 2]*100 + cur_arr[18 - cs*5 + 3] * 10 + cur_arr[18 - cs*5 + 4]] += 1;
        }
    }
    
    for (int i = 1; i < 100000; i++){
        freq[i] += freq[i-1];
    }
    
    int new_arr_list[1000000][18];
    
    for (int i = N-1; i >= 0; i--){
        int pos;
        int cur_arr[18];

        for (int index = 0; index < 18; index++){
            cur_arr[index] = arr_list[i][index];
        } 

        if (cs == 4){
            pos = cur_arr[0]*100 + cur_arr[1] * 10 + cur_arr[2];
        } else{
            pos = cur_arr[18 - cs*5] * 10000 + cur_arr[18 - cs*5 + 1] * 1000 + cur_arr[18 - cs*5 + 2]*100 + cur_arr[18 - cs*5 + 3] * 10 + cur_arr[18 - cs*5 + 4];
        }
        
        for (int index = 0; index < 18; index++){
            new_arr_list[freq[pos] - 1][index] = arr_list[i][index];
        }
        
        freq[pos] --;
    }
    
    for (int i = 0; i < N; i++){
        for (int index = 0; index < 18; index++){
            arr_list[i][index] = new_arr_list[i][index];
        }
    }
    **/
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int T;
    int arr_index = 0;
    cin >> T;
    int arr_list[1000000][18];
    int max_len = 0;

    for (int testcase = 0; testcase < T; testcase ++){
        string a;
        cin >> a;

        int a_len = a.length();
        if (a_len > max_len){
            max_len = a_len;
        }

        int arr_entry[18];
        for (int i = 0; i < a_len ; i++){
            arr_entry[18 - a_len + i] = a[i] - 48;
        }

        for (int i = 0; i < 18 - a_len; i++){
            arr_entry[i] = 0;
        }
        
        for (int index = 0; index < 18; index++){
            arr_list[arr_index][index] = arr_entry[index];
            cout << arr_entry[index];
            cout << arr_list[arr_index][index];
        }
        
        for (int index = 0; index < 18; index++){
            cout << arr_list[arr_index][index];
        }

        arr_index ++;
    }
    /**
    for (int c = 1; c < 5; c++){
        
        if (max_len > (c-1)*5){
            step(arr_list, c, T);
            
            for (int i = 0; i < T; i++){
                int is_leading_zero = 1;
                
                for (int j = 0; j < 18; j++){
                    if (is_leading_zero == 0){
                        cout << arr_list[i][j];
                    }else{
                        if (arr_list[i][j] != 0){
                            is_leading_zero = 0;
                            cout << arr_list[i][j];
                        }
                    }
                }
                cout << " ";
            }
            cout << "\n";
        } 
    }
    **/
}

I'm assuming this is a common error, and that I'm missing something simple that gives me segfaults for values I already assigned data to.

Does anyone know why this is happening?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • There's a whole lot of loops in your code, some of which are commented out. Which one exactly is giving you problems? How is the value of `arrayindex` set during that loop? – Nathan Pierson Aug 04 '21 at 23:01
  • 1
    Confused Dude, Why use `100000` in `for (int i = 1; i < 100000; i++){` instead of `1000000`? – chux - Reinstate Monica Aug 04 '21 at 23:33
  • Confused, IN various places, add a check to the `freq[]` index to verify it is in range. What value is `T`? – chux - Reinstate Monica Aug 04 '21 at 23:35
  • @OP `int new_arr_list[1000000][18];` -- Even if this worked, why do you want an array this large? This is a sign of just doing things in a lazy fashion instead of thinking a little bit more about the problem you're trying to solve. Dynamic allocation, a better data structure, maybe a dynamic container that fits the exact data you're expecting instead of the moonshot of 1000000, etc. were all viable alternatives. – PaulMcKenzie Aug 05 '21 at 00:56

1 Answers1

3

You are allocating 72 MB on the stack:

int main()
{
    [...]
    int arr_list[1000000][18];
    [...]
}

This is probably causing a stack overflow.

On the Microsoft Windows platform, the maximum stack size is, by default, 1 MB. On Linux, it is typically 8 MB.

When allocating such large amounts of memory, I recommend that you instead either use

  • dynamic memory allocation, or
  • a global variable, or
  • a static local variable.

This ensures that the array is not stored on the stack.

Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39
  • The OP may have designed their own OS that has a large enough default stack to handle such a mammoth array. – Eljay Aug 04 '21 at 23:17
  • 1
    @Eljay: It is not necessary to "design your own OS" in order to change the default stack size. On Windows, you can [set it in the linker options](https://learn.microsoft.com/en-us/cpp/build/reference/f-set-stack-size?view=msvc-160). On Linux, you can [use `setrlimit`](https://stackoverflow.com/questions/2279052/increase-stack-size-in-linux-with-setrlimit) or [edit the file `limits.conf`](https://codeforces.com/blog/entry/80688). – Andreas Wenzel Aug 04 '21 at 23:34
  • You are right the size of the array was causing this (didn't get this error with smaller arrays). Managed to not get segfaults when I declared the array outside main(). Thank you so much I was stuck on this for quite a while! – Confused Dude Aug 04 '21 at 23:41
  • @ConfusedDude: In principle, there is nothing wrong with using large amounts of memory. Since modern PCs have several GBs of RAM, it is important to know how to use these large amounts of memory. The most important rule is not to allocate such large amounts of memory on the stack. – Andreas Wenzel Aug 04 '21 at 23:54
  • @AndreasWenzel • As high as 72 MB? It's been a while, maybe that's allowed now. Last time I tried, 64 MB was the limit on my OS. – Eljay Aug 04 '21 at 23:55
  • @ConfusedDude a variable defined at global or namespace scope don't come from automatic storage (typically the stack) and are not bound by its (usually) limited size. See [static storage duration](https://en.cppreference.com/w/cpp/language/storage_duration) for more information. – user4581301 Aug 05 '21 at 00:26