struct definition inside main() causing Segmentation Fault

8.7k views Asked by At

Is it not possible to define structure inside main() . I tried the following only to get a Segmentation Fault:

#include <stdio.h>
#include <unistd.h>
#include <strings.h>
#define TRUE 1


void main(int argc,char **argv)
{
struct test_struct
{

        char test_name[50];
        char summary_desc[200];
        char result[50];
};

struct suite_struct
{
        char suite_name[50];
        struct test_struct test[500];
        int test_count;
        int passed;
        int failed;
        int unresolved;
        int notrun;
}suite[500];

        int a,b;

        for (a=0;a<500;a++)
        {
                strcpy(suite[a].suite_name,"");
                for (b=0;b<500;b++)
                {
                        strcpy(suite[a].test[b].test_name,"");
                        strcpy(suite[a].test[b].summary_desc,"");
                        strcpy(suite[a].test[b].result,"");
                }
                suite[a].test_count=0;
                suite[a].passed=0;
                suite[a].failed=0;
                suite[a].unresolved=0;
                suite[a].notrun=0;
        }
}

But the moment I take the struct definition outside it works:

#include <stdio.h>
#include <unistd.h>
#include <strings.h>
#define TRUE 1


struct test_struct 
{ 

        char test_name[50]; 
        char summary_desc[200]; 
        char result[50]; 
}; 

struct suite_struct 
{ 
        char suite_name[50]; 
        struct test_struct test[500]; 
        int test_count; 
        int passed; 
        int failed; 
        int unresolved; 
        int notrun; 
}suite[500]; 
void main(int argc,char **argv)
{

        int a,b;

        for (a=0;a<500;a++)
        {
                strcpy(suite[a].suite_name,"");
                for (b=0;b<500;b++)
                {
                        strcpy(suite[a].test[b].test_name,"");
                        strcpy(suite[a].test[b].summary_desc,"");
                        strcpy(suite[a].test[b].result,"");
                }
                suite[a].test_count=0;
                suite[a].passed=0;
                suite[a].failed=0;
                suite[a].unresolved=0;
                suite[a].notrun=0;
        }
}

Not sure why this is happening. I am using the Solaris SunStudio compiler for this.

5

There are 5 answers

5
NPE On BEST ANSWER

In the first example, suite lives on the stack, and in the second it lives on the data segment.

Since suite is quite large (~75MB), the segfault is almost certainly due to your program running out of stack space.

In most cases, it is best to allocate large data structures on the heap (using malloc() et al). This will also make it possible to allocate just the amount of space you require instead of always allocating space for 500 elements.

0
Susam Pal On

It is okay to declare a structure inside main. But in your program, the problem has got to do with the fact that you are creating 500 objects of that structure inside main function. Each object is about 15 KB in size. So, 500 objects require about 75 MB. Try printf("size: %lu\n", sizeof suite);.

You don't have that much of stack available by default. You can find the available stack using the command ulimit -s. It prints the available stack in KBs.

You can use the ulimit command to increase the stack. e.g. ulimit -s 100000.

A better approach is to dynamically allocate the memory you require using malloc().

0
Basile Starynkevitch On

It is legal to define a struct and to declare a local variable of that struct inside any function, including main.

But a code can be syntactically legal and crash at runtime (e.g. because it has an undefined behavior, per the C standard, or because it hits some system limitation, like a limit on the call stack).

2
arsenm On

The struct you define outside of main is global and uninitialized so it will go into the .bss segment and be initialized to 0 at the start of execution. The struct you define inside main is huge and exceeds the maximum stack size (which is about 1-2MB on Linux and probably Solaris too). Since the one outside of main is not on the stack, it appears to work in that case and not the other.

0
Mike Sherrill 'Cat Recall' On

In addition to answers about stack space, malloc, and undefined behavior . . .

When I tried to compile your code, I got 3 warnings.

test.c:7:6: warning: return type of ‘main’ is not ‘int’
test.c: In function ‘main’:
test.c:32:17: warning: implicit declaration of function ‘strcpy’
test.c:32:17: warning: incompatible implicit declaration of built-in function ‘strcpy’

Return an int for main, not void.

int main(int argc,char **argv)

In C, the header for strcpy is string.h, not strings.h.