user769708
user769708

Reputation: 39

Segmentation Fault in C (array related)

I wrote a code in c in order to solve Project Euler Problem 45 (https://projecteuler.net/problem=45). I keep getting segmentation fault error 139. I am sure it is not about trying to access a memory location that I do not have permission for.

My guessing is , the problem is related to sizes of my arrays. I looked up the answer and it is some 10 digit number. To get that ten digit number the size of the array "triangle" has to be something between one million and two million. But when I make the array that big i get the error. I don't get the error in the code below since size of that array is 500 000 (but of course that is not enough).

I use ubuntu 16.04 and Geany.

If you need more information please ask. Thanks in advance.

#include <stdio.h>
#include <stdlib.h>

unsigned long pentagonalgenerator(int n);
unsigned long trianglegenerator(int n);
unsigned long hexagonalgenerator(int n);

_Bool search_function(unsigned int to_be_looked_for , unsigned long array[] , int sizeofarray);

int main(void)
{
unsigned long pentagon[28000] = {0};
int sizeofpentagon = 28000;

unsigned long hexagon[100000] = {0};
int sizeofhexagon = 100000;

unsigned long triangle[500000] = {0};
int sizeoftriangle = 500000;

int counter;

for(counter = 0 ; counter < sizeofpentagon ; counter++)
{
    pentagon[counter] = pentagonalgenerator(counter + 2);
}

for(counter = 0 ; counter < sizeofhexagon ; counter++)
{
    hexagon[counter] = hexagonalgenerator(counter + 2);
}

for(counter = 0 ; counter < sizeoftriangle ; counter++)
{
    triangle[counter] = trianglegenerator(counter + 2);
}

printf("%lu \n%lu \n%lu \n", hexagon[sizeofhexagon - 1] , pentagon[sizeofpentagon - 1] , triangle[sizeoftriangle - 1]);


for(counter = 0 ; counter < sizeofhexagon ; counter++)
{
    if(search_function(hexagon[counter] , pentagon , sizeofpentagon))
    {
        if(search_function(hexagon[counter] , triangle , sizeoftriangle) && hexagon[counter] != 40755)
        {
            printf("%lu", hexagon[counter]);
            return 0;
        }
    }
}

return 1;
}

_Bool search_function(unsigned int to_be_looked_for , unsigned long array[] , int sizeofarray)
{
int left = 0, right = sizeofarray - 1 , middle = 0; 

while(left <= right)
{
    middle = (left + right) / 2;

    if(to_be_looked_for == array[middle]) return 1;
    else if(to_be_looked_for < array[middle]) right = middle - 1;
    else if(to_be_looked_for > array[middle]) left =  middle + 1;
}

return 0;
}

unsigned long pentagonalgenerator(int n)
{
unsigned int return_value = 0;

return_value = (n*(3*n - 1)) / 2;

return return_value;
}

unsigned long hexagonalgenerator(int n)
{
unsigned int return_value = 0;

return_value = n*(2*n - 1);

return return_value;
}

unsigned long trianglegenerator(int n)
{
unsigned int return_value = 0;

return_value = (n*(n + 1)) / 2;

return return_value;
}

Upvotes: 3

Views: 102

Answers (3)

Serge Ballesta
Serge Ballesta

Reputation: 148870

The maximum size for automatic variables is an implementation dependent detail. BUT major implementation have options to set it.

For example, if you are using gcc or clang, automatic variables are stored in the stack, and the stack size is controlled at link time by the option --stack <size>. The default size is 2Mb and your arrays require 628000 unsigned long so at least 5Mb.

Provided you have more standard requirements in other places of this code, I would try a 8Mb stack:

cc myprog.c -Wl,--stack -Wl,0x800000 -o myprog

(-Wl, is used to pass the argument to the linker phase of the build).

This avoids to reformat your code (for examble using allocated arrays) to only solve a compilation problem.

Upvotes: 0

Blaze
Blaze

Reputation: 16876

That's a lot of memory for the stack. Instead of this

unsigned long pentagon[28000] = {0};
int sizeofpentagon = 28000;

unsigned long hexagon[100000] = {0};
int sizeofhexagon = 100000;

unsigned long triangle[500000] = {0};
int sizeoftriangle = 500000;

Try this:

unsigned long *pentagon = calloc(28000*sizeof(unsigned long));
int sizeofpentagon = 28000;

unsigned long *hexagon = calloc(100000 * sizeof(unsigned long));
int sizeofhexagon = 100000;

unsigned long *triangle = calloc(500000 * sizeof(unsigned long));
int sizeoftriangle = 500000;

Upvotes: 5

Rishikesh Raje
Rishikesh Raje

Reputation: 8614

You have very large arrays defined as local variables in the stack. You are getting a stack overflow because of that. Arrays pentagon hexagon triangle are very large.

These need to be moved to the global space or they should be dynamically allocated. For your use case, it is easier to move the arrays to global.

unsigned long pentagon[28000] = {0};
unsigned long hexagon[100000] = {0};
unsigned long triangle[500000] = {0};

int main(void)
{
    int sizeofpentagon = 28000;
    int sizeofhexagon = 100000;
    int sizeoftriangle = 500000;
    ....

Upvotes: 2

Related Questions