3

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.

tomkaith13
  • 1,717
  • 4
  • 27
  • 39
  • 10
    `void main` **RAAAAAARRRRRRGGGGGGHHHHHH!** – pmg Jan 25 '12 at 18:09
  • 1
    You really should **learn to use a debugger**. Did you try to compile your program with warnings and debugging information enabled (with `gcc` that means `-Wall -g`)? Did you use the debugger? We could find your bug, but you really should learn to debug by yourself.... – Basile Starynkevitch Jan 25 '12 at 18:10
  • 2
    void main is illegal. The structs seem Ok. But they are rather big for automatic storage. – wildplasser Jan 25 '12 at 18:13
  • @Basile Starynkevitch: The compiler I have used is cc. And the debugger in Solaris is mdb .. the stack trace shows the following: mdb core Loading modules: [ libc.so.1 ld.so.1 ] > ::stack main+9(1, 804790c, 8047914, feffb934) _start+0x7d(1, 80479ec, 0, 80479f1, 80479fe, 8047a12) Not sure what exactly to look for from this ? There are not many tutorials to use mdb for user programs . – tomkaith13 Jan 25 '12 at 19:12
  • You still need to learn how to use your compiler (including getting all the warnings it can give you) and how to use your debugger (including understanding its messages). The C language is unsafe, and even experimented programmers need to take care of compiler warnings and to use the debugger. – Basile Starynkevitch Jan 25 '12 at 19:22
  • @Basile Starynkevitch: Thank you for your advice ... Will definitely kepp that in mind the next time . – tomkaith13 Jan 25 '12 at 19:37

5 Answers5

6

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.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • is there a way to increase stack space ? – tomkaith13 Jan 25 '12 at 18:09
  • 2
    @tomkaith13 that's the wrong question to be asking. Define the structs outside of `main()` or in a header file, and allocate space on the heap for them with `malloc()`. – Dan Fego Jan 25 '12 at 18:12
  • @aix: I was about to post the same thing, then misread your username as mine and had a complete WTF moment. – arx Jan 25 '12 at 18:12
  • @aix: its just some rough code ( the number 500) I wanted to write.. and I was lazy to create a linked list...Lesson Learnt !! :) Thanks – tomkaith13 Jan 25 '12 at 19:19
  • @aix: Sorry for bothering you but I need to ask you more details regarding the crash . I checked the solaris stack size using ulimit -Ss which is arnd 10MB. I know from the address space layour that the stack starts from 0x8048000 and grows downwards. so the stack should end at 0x76BE980.. but since suite is 75mb the new %esp value is 0x038b8364.. this is the problem ?? am i right ?? – tomkaith13 Jan 26 '12 at 02:16
3

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().

Susam Pal
  • 32,765
  • 12
  • 81
  • 103
1

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).

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
1

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.

arsenm
  • 2,903
  • 1
  • 23
  • 23
1

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.

Mike Sherrill 'Cat Recall'
  • 91,602
  • 17
  • 122
  • 185