Link to home
Start Free TrialLog in
Avatar of riscy
riscy

asked on

Stack Overflow

Help!!.

The program worked well (with init() in place) until it got bigger, after compling, it generates stack overflow error, the debug shown

"First Chance exception in ResistorCalc.exe (MFC42D.DLL):- 0xC0000FD: Stack Overflow"

I admit I use global variable but well within the dialogue classes (all public).

I am using Visual Studio V6 and working on Win98 (will plan to upgrade later to Win2000).

When replace init() with routine program, the problem goes away. Why it failed now when program got bigger or more complex?.

Please advise how to fix this and advise if I broken any visual programming rules.

Many Thanks

The programs:-

BOOL CResistorCalcDlg::OnInitDialog()
{
     CDialog::OnInitDialog();

     // Add "About..." menu item to system menu.

     // IDM_ABOUTBOX must be in the system command range.
     ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
     ASSERT(IDM_ABOUTBOX < 0xF000);

     CMenu* pSysMenu = GetSystemMenu(FALSE);
     if (pSysMenu != NULL)
     {
          CString strAboutMenu;
          strAboutMenu.LoadString(IDS_ABOUTBOX);
          if (!strAboutMenu.IsEmpty())
          {
               pSysMenu->AppendMenu(MF_SEPARATOR);
               pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
          }
     }

     // Set the icon for this dialog.  The framework does this automatically
     //  when the application's main window is not a dialog
     SetIcon(m_hIcon, TRUE);               // Set big icon
     SetIcon(m_hIcon, FALSE);          // Set small icon
     
     // TODO: Add extra initialization here
//=================================================================================

     m_CListResult.InsertColumn(0,"Value1",LVCFMT_LEFT,70);
     m_CListResult.InsertColumn(1,"Value2",LVCFMT_LEFT,70);
     m_CListResult.InsertColumn(2,"Result",LVCFMT_LEFT,70);
     m_CListResult.InsertColumn(3,"Tol",LVCFMT_LEFT,50);
     m_Required_Value=1;
     m_Initial_Value=1;
     m_Lower_Limit_Range=1;
     m_Upper_Limit_Range=100e6;
     m_Tolerance=1;
     init();                 <====== cause stack overflow error.
     UpdateData(false);
...


Avatar of captnoord
captnoord

I think you'l better change the name of the funcion becouse i think that's one of the reservered funcion of c++ and is it possible to see the source of the function
greets captnoord
ASKER CERTIFIED SOLUTION
Avatar of Salte
Salte

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of jkr
>>   init();                 <====== cause stack overflow error.

So, why don't you post the code of 'init()'?
Hmm....I am guessing here but is it possible that init is something like this:

void init()
{
   bool first_time = true;

   if (first_time) {
     first_time = false;
     call_some_other_func();
   }
}

and then call_some_other_func will eventually call init() again. The idea here is that the variable first_time should remember if you have ever called init() earlier and then only call it once. This code would work if the variable first_time had been a static variable but as written above it won't and it will cause infinite recursion.

Changing to:

   static bool first_time = true;

will fix that since then all the calls to init will share the variable first_time and once one function set it to true another call to init will do nothing.

Another error might be that it is static but it is set to false at the wrong place:

void init()
{
   static bool first_time = true;

   if (first_time) {
     call_some_other_func();
     first_time = false;
   }
}

Here the variable isn't set to true until call_some_other_func() returns, so if call_some_other_func in turn call init() again we have infinite recursion once again.

If you really need to differentiate between 'init not done', 'init in progress' and 'init complete' you should have three values and the first_time should check for 'init not done':

void init()
{
   enum {
     init_not_done,
     init_in_progress,
     init_complete,
   };

   static int init_status = init_not_done;
   if (init_status == init_not_done) {
      init_status = init_in_progress;
      call_some_other_func();
      init_status = init_complete;
   }
}

One problem here is that if init_status is not init_complete you probably should have done something else.

Also, the variable first_time or init_status or whatever you call it doesn't have to be a static variable in the function but static variable in the class, that has the same effect but other functions than init() can read/set the variable.

In particular you should be careful if you need A to be initialized before B which in turn must be initialized before C. If C then need A to be initialized first you're in trouble. So figure out what to be initialized first and in what order is here important and then write the init function accordingly.

Alf
Avatar of riscy

ASKER

Good news

I found the recursive statement deep in the program, which cause function call around 5 time per loop, this is fixed.

Many thank for very useful response, I look forward to continue learning Visual C++.

I changed init() to Startup_init() as init() is too seems generic.

Once again thank you all.

Riscy
If you are happy with the answers given you should close this question.

If you feel you managed well without the answers you can post a message in community support and ask to get the points back for this question. You can then spend those points on other questions.

If you feel that one answer helped you a lot you can accept that answer and give that expert the points.

If you feel that more than one answer helped you you can again post to community support and ask that the the points should be reduced so that you can accept this answer for one of the experts and then post a "points for <EXPERT>" posting to give those you think should get points as well. You must point one such "points for <EXPERT>" for each expert and typically you put the name of the expert instead of "<EXPERT>" so if you think jkr helped you but you accepted someone else here you can post a "Points for jkr" and when he respond to that message you can accept that message to give him the points.

In either case, don't leave the question open if you are done with it.

Alf