1

I don't understand why I am getting a stack overflow immediately when I enter the main function. I am supposed to read from a text file and do some processing. Can someone explain to me the reason and suggest how to solve it?

#include <iostream>
#include <ctime>
#include <cstdlib>
#include <fstream>
#include <iomanip>

using namespace std;
const int MAX=100;
enum countrytype{S,F};

struct dob
{
int day;
int month;
int year;
};

struct Local
{
char country[MAX];
char gender[MAX];
char name[MAX];
dob birthday;
int noofmod;
char mod[MAX][MAX];
int mark[MAX];

};

struct Foreign
{
char country[MAX];
char gender[MAX];
char name[MAX];
dob birthday;
int noofmod;
char mod[MAX][MAX];
int mark[MAX];

};

union Student
{
Local localstudent;
Foreign foreignstudent;

};

struct UOWstudent
{
countrytype ct;
Student st;

};

void readfile(ifstream &read,UOWstudent noofstudent[MAX]);

int main()
{
UOWstudent noofstudent[MAX];
ifstream read;

readfile(read,noofstudent);
cout<<endl
    <<noofstudent[0].st.foreignstudent.country
    <<endl
    <<noofstudent[0].st.foreignstudent.gender
    <<endl
    <<noofstudent[0].st.foreignstudent.name;



system("PAUSE");

}

void readfile(ifstream &read, UOWstudent noofstudent[MAX])
{
int i=0;
char country;
char filename[MAX];
cin>>filename;
read.open(filename);




    read>>country;
    /*if (country =='F')
    {
        read.getline(noofstudent[i].st.foreignstudent.country,MAX);

        read>>noofstudent[i].st.foreignstudent.gender;
        read.getline(noofstudent[i].st.foreignstudent.name,MAX);

    }

    else
        read.getline(noofstudent[i].st.foreignstudent.country,MAX);*/




}

This is my text file

F South Korea
Male Psy Park Jae Sang
31 - 12 -1977
3 CSCI114 55 CSCI103 44 GangNam
Swapnil
  • 8,201
  • 4
  • 38
  • 57
Computernerd
  • 7,378
  • 18
  • 66
  • 95
  • 1
    Your code is going to be so much more manageable if you use `std::string`. – chris Jan 05 '13 at 05:23
  • I'm not getting a stack overflow on my system. Are you sure that you're running the most up-to-date version of the executable? Can you give us the stack trace? – templatetypedef Jan 05 '13 at 05:23
  • @chris i cant use the string class – Computernerd Jan 05 '13 at 05:25
  • 3
    Your `UOWstudent` object instance is 10720 bytes wide on a 64bit platform like mine. now take 100 of those. Hmmm.... – WhozCraig Jan 05 '13 at 05:25
  • I suspect too much stack memory. One object is at least 10KB for the 2D char array, and you have 100 of those. The stack is uaully about a MB and that was just one member. – chris Jan 05 '13 at 05:25
  • @ templatetypedef ntdll.dll!76fc15de() [Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll] ntdll.dll!76fc15de() ntdll.dll!76fb014e() KernelBase.dll!75125606() > msvcr100d.dll!_unlock(int locknum) Line 375 C msvcr100d.dll!_msize_dbg(void * pUserData, int nBlockUse) Line 1536 + 0x7 bytes C++ msvcr100d.dll!_msize_dbg(void * pUserData, int nBlockUse) Line 1535 + 0xc bytes C++ – Computernerd Jan 05 '13 at 05:26
  • 2
    Life will be so much easier if you stop using raw arrays in C++, and start using [`std::vector`](http://en.cppreference.com/w/cpp/container/vector). – Some programmer dude Jan 05 '13 at 05:27
  • @JoachimPileborg, Very true, but I suspect it's out for the same reason as `std::string`. – chris Jan 05 '13 at 05:28
  • @ WhozCraig how do you know the UOWstudent object instance is 10720 btyes wide?? – Computernerd Jan 05 '13 at 05:29
  • @chris how do you calculate that one object is 10KB for the 2D array??? – Computernerd Jan 05 '13 at 05:30
  • 2
    Because I "asked"... `int main() { cout << sizeof(UOWstudent); return 0; }` – WhozCraig Jan 05 '13 at 05:30
  • @Lim, As per the standard, each `char` must be one byte, so 100 * 100 * 1B = 10KB. – chris Jan 05 '13 at 05:32
  • Why can't you use the `std::string` type or any of the standard container types? `char gender[MAX];` 100 bytes seems like an awful lot of memory to store a student's gender! – johnsyweb Jan 05 '13 at 05:36
  • @everyone thanks guys, there was a stackoverflow because the size of my object was too large, i have reduced it and it works now – Computernerd Jan 05 '13 at 05:38
  • @chris- It's not quite that a `char` must be one byte as much as `sizeof(char)` must always be one. It's possible that a `char` is actually much more than a byte, though `sizeof(char)` will still be `1` even if `char` were one megabyte. – templatetypedef Jan 05 '13 at 05:40
  • @templatetypedef, I was going to say that, but I reworded it to be more novice-friendly. This is why rewording things in the standard (at least without a note) is a bad idea :p I know what you mean, though. – chris Jan 05 '13 at 05:41

2 Answers2

8

Simply, your code is allocating all of its storage on the stack, and you are allocating more than the allowed limit.

Looking at why you are surpassing the limit is probably more useful.

The first line of main() is allocating an array of 100 (MAX = 100) students on the stack:

UOWstudent noofstudent[MAX];

How big is a UOWstudent? You can figure that out by looking at each field:

struct UOWstudent
{
    countrytype ct; // enum. let's assume 4 bytes. (32-bit executable)
    Student st;     // ???
};

How big is a student?

union Student
{
    Local localstudent;
    Foreign foreignstudent;
};

It's the size of a Local or a Foreign, so let's just look at one. We need to make another assumption about the size of char. Let's assume 1 byte (8-bit characters):

struct Local
{
    char country[MAX];  // 100 bytes
    char gender[MAX];   // 100 bytes
    char name[MAX];     // 100 bytes
    dob birthday;       // 3 ints or 12 bytes (32-bit assumption again)
    int noofmod;        // 4 bytes
    char mod[MAX][MAX]; // 10,000 bytes
    int mark[MAX];      // 400 bytes
};                      // total: 10,716 bytes

So that very first line of main() tries to allocate (10,716 + 4) x 100 = 1,072,000 bytes on the stack. And I made the most conservative assumptions about the size of char and int for your compiler settings, they may quite possibly be higher. If the stack limit is indeed one megabyte (1,048,576 bytes), then this initial allocation goes over the limit.

You can use C's sizeof operator to get information about the actual size of your types. Refer to this stackoverflow answer, discussing allocating arrays on the heap, instead of the stack, which is a good step towards solving your problem. (UOWstudent == University of Waterloo student?)

Community
  • 1
  • 1
Dave Cameron
  • 2,110
  • 2
  • 19
  • 23
1

MAX is defined as 100 (does it really need to be?) and you have a bunch of char arrays MAX elements in length, you even have a 2D array, which is ginormous. So your structs are huge and are probably going over the max stack size -- I think its 1024Kb in windows.

ash
  • 3,354
  • 5
  • 26
  • 33