could someone explain this code plz

Hello,

I'm working on a small script that uses the mysql c++ connector. I've got the demo code linked and calling the connector working just fine, but since I'm a beginner with c++ am a bit unclear about some aspects of dynamic memory.

The original code and topic discussion from which I'm taking a few snippets can be found here:

http://dev.mysql.com/doc/refman/5.1/en/connector-cpp-examples-complete-example-2.html

My question is, what is the advantage of using auto-pointers in this circumstance? Here's, the code, then I'll follow up my question with a few other points.

The portion of the original code declares the driver instance and tries to execute a few statements:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
try {
  sql::Driver *driver;
  sql::Connection *con;
  sql::Statement *stmt;
  sql::ResultSet *res;
  sql::PreparedStatement *pstmt;

  /* Create a connection */
  driver = get_driver_instance();
  con = driver->connect("tcp://127.0.0.1:3306", "root", "root");
  /* Connect to the MySQL test database */
  con->setSchema("test");

  stmt = con->createStatement();
  stmt->execute("DROP TABLE IF EXISTS test");
  delete stmt;

  /* '?' is the supported placeholder syntax */
  pstmt = con->prepareStatement("INSERT INTO test(id) VALUES (?)");
  for (int i = 1; i <= 10; i++) {
    pstmt->setInt(1, i);
    pstmt->executeUpdate();
  }
  delete pstmt;

  /* Select in ascending order */
  pstmt = con->prepareStatement("SELECT id FROM test ORDER BY id ASC");
  res = pstmt->executeQuery();
  delete res;

  delete pstmt;
  delete con;
} catch (sql::SQLException &e) {
/* run some cout catch statements */
}



The following suggestions were made for more optimized code:

1
2
3
4
5
std::auto_ptr< sql::Connection > apConn( driver->connect("tcp://127.0.0.1:3306", "root", "root" ) ) ;

std::auto_ptr< sql::Statement > apStmnt( apConn->createStatement( ) ) ;

std::auto_ptr< sql::ResultSet > apRes( apStmnt->executeQuery("SELECT 'Hello World!' AS _message") ) ;


In part, the suggestion was made with the reasoning that, should an exception occur when calling any of the sql connector commands, a memory leak is created.

1. However, I'm not clear as to whether using auto pointers would be favoured for any reason over including delete stmt;... and with con, stmt, pstmt, and res in the catch structure? In my naive newb view, either way would prevent a memory leak, wouldn't it?

2. Moreover, is it a mistake in the original code that delete driver; was not include... why would it be important to delete stmt, con, and res, and pstmt but not driver?

The other point that I'd make is that I'd like to be calling an instance of the sql connector and sending executing simple sql queries in a multi-threaded context... so this code would be part of a worker thread, using boost.

Thanks,
Brian

Last edited on
I dont know much about linking to mySql, but I believe auto is a new feature for c++11, and not all compilers even support it yet. So either way of handling it would work fine.
ResidentBiscuit is confusing C++11's auto and std::auto_ptr. Note that std::auto_ptr was deprecated in C++11 in favour of std::unique_ptr. In this code the difference between the two doesn't matter.

1. If an exception is thrown inside the try block the code will first run destructors for all the objects that has been declared inside the try block so far. After that the code will continue with the catch block... The destructor of a pointer will do nothing so the objects they pointed to will still exist somewhere in memory but we can't reach them so we have a memory leak. The destructors of std::auto_ptr on the other hand, will use delete to free the objects that they point to so you don't get a memory leak here.

2. get_driver_instance() returns a pointer to a sql::Driver object. The word "get" in the function name suggests it will not create a new object, but only return a pointer to some existing object. You can't be sure how this object was created. Only if it was dynamically allocated with new it should be freed with delete. It is probably the function or the library that the function belongs to that is responsible for making sure the object is freed correctly, so you should not try to free it.
Thanks for the replies. Peter, that is exactly the kind of response I was hoping to get! That makes the answers perfectly clear and understandable.
Cheers!
Brian
Topic archived. No new replies allowed.