I checked the code and all the binding in records is done using the new keyword to create an info structure. Those structures are added to maps which are used to store them. Those pointers are saved in the map as bare pointers. The result is that they never get released!
At this time I propose to derive the info structures from the object class so we have the addref() and release() function calls, then use a smart pointer of these in the maps.
Note that you cannot call release() on an object you allocated on the stack. This will call the delete on the object which is wrong considering the situation (i.e. new was never called on the object.)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It made no difference.
Just a stupid idea but maybe the smartpointer does not work on the stack... Why not create a destructor of the dynamic_record to destroy the maps with iterators instead ?
A note : the patch is odd. It adds code which has nothing to do with the current bug. I know it because the code is from a bug we have discussed a long time ago, which I fixed in my version, but surprisingly was not present in 1.6. I also suggest you update the "news", cos there are no records about the changes.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'm not too sure why you think that the record would not be freed. The stack works in such a way that it cannot be have been freed. The record structure may still look like it's there, but you cannot safely use that block of memory.
However, it very much looks like the bound info structures weren't released. Looking at the code, the same pointer may be saved in one or two locations. It's easier to use a smart pointer to handle those special cases automatically and avoid double delete calls.
So... isn't this one bug the one you were asking me to look at again? And what did you do to fix the problem on your end?
Thank you.
Alexis
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Well,
- Simply create a function request which get a row of a database table.In this function
- allocate on the stack a dynamic_record
- do a fetch from your statement to get data on the dynamic_record stmt->fetch(rec)
Now put a breakpoint on the fetch part and start the program. Use a memory tool and check memory used by the fetch statement (storing in the dynamic_record).
And check again AFTER the function, the exact memory which has been taken is still there.
We massively use this function, and we loose 2MB each call. Our program has "sequences" which do 10 of these calls, so each sequence we loose 20MB. After 5 sequence there is a hole of 100MB in the program, so in the end the program will fail to allocate data because the memory allocator pointer is lost with many holes in different places.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
memory leak
This is correct.
I checked the code and all the binding in records is done using the new keyword to create an info structure. Those structures are added to maps which are used to store them. Those pointers are saved in the map as bare pointers. The result is that they never get released!
At this time I propose to derive the info structures from the object class so we have the addref() and release() function calls, then use a smart pointer of these in the maps.
Note that you cannot call release() on an object you allocated on the stack. This will call the delete on the object which is wrong considering the situation (i.e. new was never called on the object.)
Fix for the memory by transforming a set of bare pointers in smart pointers.
There is a patch against version 1.6
(1.7 is an intermediate version, it does not include this fix.)
Let me know whether that works for you.
It made no difference.
Just a stupid idea but maybe the smartpointer does not work on the stack... Why not create a destructor of the dynamic_record to destroy the maps with iterators instead ?
A note : the patch is odd. It adds code which has nothing to do with the current bug. I know it because the code is from a bug we have discussed a long time ago, which I fixed in my version, but surprisingly was not present in 1.6. I also suggest you update the "news", cos there are no records about the changes.
I put updates on the Freecode website.
http://freecode.com/projects/odbcpp
I'm not too sure why you think that the record would not be freed. The stack works in such a way that it cannot be have been freed. The record structure may still look like it's there, but you cannot safely use that block of memory.
However, it very much looks like the bound info structures weren't released. Looking at the code, the same pointer may be saved in one or two locations. It's easier to use a smart pointer to handle those special cases automatically and avoid double delete calls.
So... isn't this one bug the one you were asking me to look at again? And what did you do to fix the problem on your end?
Thank you.
Alexis
Well,
- Simply create a function request which get a row of a database table.In this function
- allocate on the stack a dynamic_record
- do a fetch from your statement to get data on the dynamic_record stmt->fetch(rec)
Now put a breakpoint on the fetch part and start the program. Use a memory tool and check memory used by the fetch statement (storing in the dynamic_record).
And check again AFTER the function, the exact memory which has been taken is still there.
We massively use this function, and we loose 2MB each call. Our program has "sequences" which do 10 of these calls, so each sequence we loose 20MB. After 5 sequence there is a hole of 100MB in the program, so in the end the program will fail to allocate data because the memory allocator pointer is lost with many holes in different places.
no news ?