Stack overflow in 'C:\Program Files\MetaTrader 4\MQL4\Experts\FxCashEarner Vs.1.0.ex4'

 

Hi everyone in the house,

Please I encountered this problem for the first time and I don't know how to solve it:

Stack overflow in 'C:\Program Files\MetaTrader 4\MQL4\Experts\FxCashEarner Vs.1.0.ex4'

Anytime I compile my ea, that is the message it gives to me.

Thanks in advance

 
How shall we help without code?
 

Opengates:

Stack overflow in 'C:\Program Files\MetaTrader 4\MQL4\Experts\FxCashEarner Vs.1.0.ex4'

Anytime I compile my ea, that is the message it gives to me.

  1. Impossible; that is not a compile message, it is a runtime message. When you compile, it will restart your EA if already attached to a chart.
  2. You are calling a function recursively. No mind readers here; No code, no other help possible.
 
Opengates:

Hi everyone in the house,

Please I encountered this problem for the first time and I don't know how to solve it:

Stack overflow in 'C:\Program Files\MetaTrader 4\MQL4\Experts\FxCashEarner Vs.1.0.ex4'

Anytime I compile my ea, that is the message it gives to me.

Thanks in advance

Stack overflow can happen when you have a local array(s) and you put too much information in there . You may have to declare some of theme globally (not to confuse with global variables of the terminal) or declare as static, e.g. static int array[ ] ; so essentially the limit becomes the RAM of your computer  (the heap)

 

best regards 

 
string ReadIni;
 // reading database credentials from INI file
 Host = "ReadIni(INI, MYSQL, pHost)";
 User = "ReadIni(INI, MYSQL, pUser)";
 Password = "ReadIni(INI, MYSQL, pPassword)";
 Database = "ReadIni(INI, MYSQL, pDatabase)";
 Port     = StrToInteger("ReadIni(INI, MYSQL, pPort)");
 Socket   = "ReadIni(INI, MYSQL, pSocket)";
 ClientFlag = StrToInteger("ReadIni(INI, MYSQL, pClientFlag)");  

 Print ("Host: ",Host, ", User: ", User, ", Database: ",Database);
 
 // open database connection
 Print ("Connecting...");
 
 DB = MySqlConnect(Host, User, Password, Database, Port, Socket, ClientFlag);
 
 if (DB == -1) { Print ("Connection failed! Error: "+MySqlErrorDescription); return(0); } else { Print ("Connected! DBID#",DB);}
 
 // executing SELECT statement
 int      vSubcode,vFxacctno,vAccesscode,i,Cursor,Rows;
 string   vUsername,vPassword,FXOpen,Query;
 datetime vExpirydate,MyExpiryDate;
  
 Query = "SELECT username, password, accesscode, expirydate, subcode, fxacctno FROM table";
 Print ("SQL> ", Query);
 Cursor = MySqlCursorOpen(DB, Query);
 
 if (Cursor >= 0)
    {
     Rows = MySqlCursorRows(Cursor);
     Print (Rows, " row(s) selected.");
     for (i=0; i<Rows; i++)
     
         if (MySqlCursorFetchRow(Cursor)) {
             vUsername = MySqlGetFieldAsString(Cursor, 1);     //
             vPassword = MySqlGetFieldAsString(Cursor, 2);     //
             vFxacctno = MySqlGetFieldAsInt(Cursor, 3);     //
             vAccesscode = MySqlGetFieldAsInt(Cursor, 7);      //
             vExpirydate = MySqlGetFieldAsDatetime(Cursor, 8); //
             vSubcode = MySqlGetFieldAsInt(Cursor, 9);        //
           
            if(MyUsername!=vUsername) {
            Print("This username is not existing in our database!"); return(0); 
            }
            
            if(MyPassword!=vPassword) {
            Print("Incorrect password! Try again."); return(0);
            }
            
            if(AccessCode!=vAccesscode) {
            Print("Access Code entered is either incorrect, expired or you are not authorized to use this software!"); return(0);
            }
            
            if(MySubIdCode!=vSubcode) {
            Print("Enter correct subscription identification code!"); return(0);
            }
            
            MyExpiryDate = vExpirydate;
            if(TimeCurrent()>MyExpiryDate) {
            Print("Your access code has expired and as a result, your access period is over" + TimeToStr(MyExpiryDate,TIME_DATE|TIME_SECONDS),"Renew your subscription today @ www.fxdominion.com/245dea");
            return(0);  } 
            
            if(AccountNumber()!=vFxacctno) {
            Comment("Unauthorized User! Get for your own copy @ www.mysite.com today!",GetLastError());
            Print("Unauthorized User! Get for your own copy @ www.mysite.com today!",GetLastError());
            return(0); 
            }
            
     MySqlCursorClose(Cursor); // NEVER FORGET TO CLOSE CURSOR !!!
    }  else   {
     Print ("Cursor opening failed. Error: ", MySqlErrorDescription);
    }  
 MySqlDisconnect(DB);
 Print ("Disconnected. Script done!");
} 
 

Above is the codes that is giving me stack overflow error.

Thanks everyone!

 

Place some Prints(__LINE__, ...) with other usefull info like e.g. rows and i in your code to determine exactly where your Sql-Request (my guess) gets crazy.

 

Opengates:

string ReadIni;
 // reading database credentials from INI file
 Host = "ReadIni(INI, MYSQL, pHost)";
 User = "ReadIni(INI, MYSQL, pUser)"

 Hello,


a) when you have a function that returns a string, such as ReadIni(), assignment to a variable goes like

User = ReadIni(INI, MYSQL, pUser);

that is, without the quotes " "

 

b) 

if (Cursor >= 0)
   {     

    Rows = MySqlCursorRows(Cursor);

    Print (Rows, " row(s) selected.");    

    for (i=0; i<Rows; i++)    

         if (MySqlCursorFetchRow(Cursor)) {

             vUsername = MySqlGetFieldAsString(Cursor, 1);     //

             vPassword = MySqlGetFieldAsString(Cursor, 2);     //

             /************

                          rest of code

                                      ************/

            if(AccountNumber()!=vFxacctno) {

            Comment("Unauthorized User! Get for your own copy @ www.mysite.com today!",GetLastError());

            Print("Unauthorized User! Get for your own copy @ www.mysite.com today!",GetLastError());

            return(0); 

            }            

     MySqlCursorClose(Cursor); // NEVER FORGET TO CLOSE CURSOR !!!

    }  else   {

     Print ("Cursor opening failed. Error: ", MySqlErrorDescription);

    }  

 

Here, I highlighted where  if starts and ends. So essentially, you are closing the Cursor on the first iteration of for, and I may guess that the if will no longer evaluate as true

if (MySqlCursorFetchRow(Cursor))

 

c) You have a syntax of

for (i=0; i<Rows; i++)

if    /*     */

else    /*      */

  which is ok as you write here; i only quote as to warn for the possible lack of curly braces { } on a general aspect

 

for (i=0; i<rows; i++)
{
    /* code goes here */
}

 

best regards 

 
Demos:

 Hello,


a) when you have a function that returns a string, such as ReadIni(), assignment to a variable goes like

that is, without the quotes " "

 

b) 

 

Here, I highlighted where  if starts and ends. So essentially, you are closing the Cursor on the first iteration of for, and I may guess that the if will no longer evaluate as true

 

c) You have a syntax of

  which is ok as you write here; i only quote as to warn for the possible lack of curly braces { } on a general aspect


@Demos: Thanks, will work on your suggestions and get back to you whatever it is. Later

 

 

best regards 

 

@Demos: Tried everything you suggested but the result still remained the same - Stack Overflow!

Thanks anyway, you are nice, appreciate

 

I initially shared the opinion that an excessive recurison could lead into a stack overflow. Internally the code puts all the return values as well as registers onto the stack (far down on the machine code level). But then I saw this and feel irritated:

 Cursor = MySqlCursorOpen(DB, Query);
 
 if (Cursor >= 0)
    {
     Rows = MySqlCursorRows(Cursor);
     Print (Rows, " row(s) selected.");
     for (i=0; i<Rows; i++)
     
         if (MySqlCursorFetchRow(Cursor)) {
             vUsername = MySqlGetFieldAsString(Cursor, 1);     //
             vPassword = MySqlGetFieldAsString(Cursor, 2);     //
             vFxacctno = MySqlGetFieldAsInt(Cursor, 3);     //
             vAccesscode = MySqlGetFieldAsInt(Cursor, 7);      //
             vExpirydate = MySqlGetFieldAsDatetime(Cursor, 8); //
             vSubcode = MySqlGetFieldAsInt(Cursor, 9);        //
           
            if(MyUsername!=vUsername) {
                ...
            }
            
     MySqlCursorClose(Cursor); // NEVER FORGET TO CLOSE CURSOR !!!
    }  else   {
     Print ("Cursor opening failed. Error: ", MySqlErrorDescription);
    }  
 MySqlDisconnect(DB);

If I am not mistaken, you are closing the MySqlCursorClose repeatly in the for loop.

Usually from rough guessing:

  1. MySqlConnect
  2. MySqlCursorOpen
  3. for (...) {
  4. ... code magic!
  5. }
  6. MySqlCursorClose
  7. MySqlDisconnect 
But you seem to have done:

  1. MySqlConnect
  2. MySqlCursorOpen
  3. for (...) {
  4. ... code magic!
  5. MySqlCursorClose // repeated close over and over again (the entire for loop and the intern if clause). E.g. multiple closures.
  6. }
  7. MySqlDisconnect

This might cause a stack overflow because the internal code of MySqlCursorClose seem to try looping through all kind of pointers and can not find the correct one to close. Looping over and over until a stack overflow occours.

Note: This is just a rough guess from quickly peeking over your posted code. I might be wrong. Simply try commenting the CursorClose (not closing it at all) and see what happens.

Edit: From the bad styling I guess that the MySqlCursorClose and the else statement afterwards is part of the inner if clause within the for loop. 

Reason: