0

Dear StackOverflow'ers,

I've been getting into coding with C++ and I took a project where I read information out of a 4D SQL database into MySQL syntax .sql files which in turn get executed by an MySQL server. I'm running into the following problem; if I run the CreateSQL function with one table and then exit the programme, it runs fine.

If I loop the CreateSQL function to create SQL from all tables, it fails with a std::bad_alloc error.

Since I'm pretty new with C++, I was hoping if some of the more experienced C++ programmers could point me in the direction where this error could occur. My (unexperienced) guess would be incorrect freeing of variables or the timing of this, as follows:

SQLFreeHandle( SQL_HANDLE_STMT, hStmt ) ;
SQLFreeHandle( SQL_HANDLE_DBC, hConn ) ;
SQLFreeHandle( SQL_HANDLE_ENV, hEnv ) ;

Any help would be greatly appreciated.

The full source code is below:

Source code

EDIT: Following François' advice from the comments:

for( int i = 1 ; i <= numRows ; i++ )
{
// Datatypes
// SQLGetData

char buf[256];
SQLINTEGER numBytes ;
newFile << createInsert(table);
for( int j = 1 ;
  j <= numCols ;
  j++ )
{

  retCode = SQLGetData(

    hStmt,
    j,           // COLUMN NUMBER of the data to get
    SQL_C_CHAR,  // the data type that you expect to receive
    buf,         // the place to put the data that you expect to receive
    255,         // the size in bytes of buf (-1 for null terminator)
    &numBytes    // size in bytes of data returned

  ) ;

    if( CHECK( retCode, "SqlGetData", false ) )
    {
        retCode2 = SQLDescribeColA( hStmt, j, colName, 255, &colNameLen, &dataType, &columnSize, &numDecimalDigits, &allowsNullValues ) ;
        if( CHECK( retCode2, "SQLDescribeCol" ) )
        {
            //cout << dataType << endl;
            if(dataType != 91) {
                newFile << "'" << removeSlashes(removeSpecials(buf)) << "'";
            }
            else if (dataType == 91) {
                newFile << "date_format(str_to_date('" << fixDate(buf) << "', '%d-%m-%Y'),'%Y-%m-%d')";
            }
        }
    //Sleep(50);
    }
    if(j != numCols) {
        newFile << ",";
    }

}
newFile << ");\n";
cout << "Regel #" << i <<  " van tabel " << table << " is verwerkt." << endl;

retCode = SQLFetch( hStmt ) ;
if( !SQL_SUCCEEDED( retCode ) )
{
  cout << "Tabel "+table+" is verwerkt." << endl;
  printf( "Regel %d is de laatste regel.\n", i ) ;
}
}
Vexation
  • 23
  • 5
  • [This `std::bad_alloc` reference](http://en.cppreference.com/w/cpp/memory/new/bad_alloc) might help explain what it's about. You're correct that it has to do with dynamically allocated memory, but not *freeing* it. – Some programmer dude Jun 27 '17 at 13:43
  • Thank you for your speedy reply, I shall look into that! – Vexation Jun 27 '17 at 13:44
  • Users are more likely to pay attention to your question if you provide a [MCVE]. Providing a link to your code (not supplying it directly in the question) and providing such a large amount of it will discourage most users from considering your question. – François Andrieux Jun 27 '17 at 13:45
  • You never free `array` in any of your functions. – Hatted Rooster Jun 27 '17 at 13:45
  • Thank you @FrançoisAndrieux for your constructive feedback, I will correct this. GillBates, I am familiar with clearing arrays in PHP, however not with the exact workings of this in C++, I shall read into this, thank you for your advice! – Vexation Jun 27 '17 at 13:47
  • Just keep using `std::string` like you're doing, no need for any `new` allocations, remove those. – Hatted Rooster Jun 27 '17 at 13:52
  • @GillBates Thank you for your constructive replies. – Vexation Jun 27 '17 at 13:58

1 Answers1

0

std::bad_alloc is thrown by new when it fails to allocate memory, usually because of memory exhaustion which usually indicates a memory leak somewhere in your program.

Your functions createInsert and createSelect are both littered by dynamic allocation that you do not delete :

char * array = new char[array_size];

Instead of dynamically allocating like this, you should use std::string and operator>> to extract from an ifstream and steer away from any dynamic allocation, there is always a better approach than manual allocation.


Side note, while(!file.eof()) is always bad.

Hatted Rooster
  • 33,170
  • 5
  • 52
  • 104
  • Thank you for the tip on the `while(!file.eof())`, I was not aware of this. And generally, thank you for your great help! – Vexation Jun 29 '17 at 06:25