![]() | |
![]() |
| | Thread Tools | Display Modes |
#1
| |||
| |||
|
#2
| |||
| |||
|
|
I am selecting 4 columns from a mysql table defined as double NOT NULL default '0' On line 4 below, a BadConversion exception is thrown, with the what() message of: Tried to convert "0.00P\uffffI" to a "d The \uffff is output as a block font. The conversion to \uffff is done by, I believe, GNOME's copy/paste. 1 double wpc1 = (double)row["wpc_slicing"]; 2 double wpc2 = (double)row["wpc_piercing"]; 3 double wpc3 = (double)row["wpc_chopping"]; 4 double wpc4 = (double)row["wpc_bludgeoning"]; The first three lines are converted fine. The values print out in my log as expected (I've omitted that code), which really puzzles me, because the value in the columns of the third and the fourth row are the same (0.0075). Any ideas what is causing the bad conversion and the (apparently) malformed error message? Drew Vogel |
#3
| |||
| |||
|
|
On line 4 below, a BadConversion exception is thrown, with the what() message of: Tried to convert "0.00P\uffffI" to a "d |
stringstream outs;
#4
| |||||
| |||||
|
|
Drew Vogel wrote: On line 4 below, a BadConversion exception is thrown, with the what() message of: Tried to convert "0.00P\uffffI" to a "d I don't know why the message is truncated. Try the attached patch, to see if the symptom changes. It just changes the way this message is constructed. As for why the error occurs, if the data truly is accurately represented in that error, then there's no wonder it runs into a bad conversion. That most definitely is not a valid double. What do you get when you use the basic 'mysql' command-line client to dump the data from this row? What if you try casting that fourth field to a std::string instead? |
|
id | name | max_health | max_strength | max_agility | wpc_slicing wpc_piercing | wpc_chopping | wpc_bludgeoning | +----+----------+------------+--------------+-------------+-------------+--------------+--------------+-----------------+ 1 | knight | 100 | 100 | 75 | 0.01 0.0075 | 0.0075 | 0.0075 | 2 | assassin | 90 | 80 | 100 | 0.0075 0.01 | 0.005 | 0.005 | +----+----------+------------+--------------+-------------+-------------+--------------+--------------+-----------------+ |
|
wpc_slicing | wpc_piercing | wpc_chopping | wpc_bludgeoning | +-------------+--------------+--------------+-----------------+ 0.01 | 0.0075 | 0.0075 | 0.0075 | 0.0075 | 0.01 | 0.005 | 0.005 | +-------------+--------------+--------------+-----------------+ |
|
Table | Create Table | |
|
character_classes | CREATE TABLE `character_classes` ( `id` int(10) unsigned NOT NULL auto_increment, |
#5
| |||
| |||
|
|
If I select all of the columns in the table (named, not using *), the last column (wpc_bludgeoning) is corrupted. When I select just the four wpc_* columns, the data in the third column (wpc_chopping) corrupted. In both scenerios, it corrupts the data in the last or third rows, respectively, for both rows in the result set. |
#6
| |||
| |||
|
|
Drew Vogel wrote: If I select all of the columns in the table (named, not using *), the last column (wpc_bludgeoning) is corrupted. When I select just the four wpc_* columns, the data in the third column (wpc_chopping) corrupted. In both scenerios, it corrupts the data in the last or third rows, respectively, for both rows in the result set. Sounds like you have a memory bug somewhere. While it's possible that it is in MySQL++, you'd think that someone else would have run into something this blatant before. If you're running on a Linux or OS X machine, try running your program under valgrind. If on Windows, you may only have the choice of commercial programs like Bounds Checker. |
#7
| |||
| |||
|
|
I am using the State Threads library, but the library never actually creates a new thread |
|
Any ideas how closing or not closing the Connection object (well after the conversion is made) could have any effect on the conversion? |
#8
| |||
| |||
|
|
Drew Vogel wrote: I am using the State Threads library, but the library never actually creates a new thread Are you rebuilding MySQL++ with thread support, and linking your code to the thread-safe version of the MySQL C API library? Are you observing the thread safety requirements spelled out in the MySQL C API documentation? State Threads aren't preemptible. All mysql queries (at least at this |
|
Any ideas how closing or not closing the Connection object (well after the conversion is made) could have any effect on the conversion? Connection objects are designed to last the lifetime of the program, if necessary. You do not have to close it in order to get good data. I think all you have done is perturbed your bug into hiding from you; it's still there, waiting to bite you again. Right, I'm closing the Connection object right before main() returns -- |
#9
| |||
| |||
|
|
Warren Young wrote: Drew Vogel wrote: If I select all of the columns in the table (named, not using *), the last column (wpc_bludgeoning) is corrupted. When I select just the four wpc_* columns, the data in the third column (wpc_chopping) corrupted. In both scenerios, it corrupts the data in the last or third rows, respectively, for both rows in the result set. Sounds like you have a memory bug somewhere. While it's possible that it is in MySQL++, you'd think that someone else would have run into something this blatant before. If you're running on a Linux or OS X machine, try running your program under valgrind. If on Windows, you may only have the choice of commercial programs like Bounds Checker. I'm not sure I actually solved this, but it went away. I went over the execution path once more today (think fresh eyes might catch something new). I realized that the Connection object was never closed or deleted. I added a call to ->close() and a delete statement. Now the data corruption is gone. I am using the State Threads library, but the library never actually creates a new thread (the exception was being thrown in the startup code, before new threads are needed) so it is unlikely that this was causing a problem. Any ideas how closing or not closing the Connection object (well after the conversion is made) could have any effect on the conversion? If anything, I would think that the data corruption would happen if the conversion happened _after_ the connection was closed. |
#10
| |||
| |||
|
|
After running into this same memory corruption again, I did a bit more debugging. Through trial and error, I've determined that it only happens when I declare a row object and then initialize it later: mysqlpp::Row row; while (row = res.fetch_row()) { ... } The memory corruption does not appear if I declare the row object inside the loop condition: while (mysqlpp::Row row = res.fetch_row()) { ... } |
![]() |
| Thread Tools | |
| Display Modes | |
| |