Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem in OCI_CollFree() #1

Closed
weexp opened this issue Jun 25, 2015 · 6 comments
Closed

Problem in OCI_CollFree() #1

weexp opened this issue Jun 25, 2015 · 6 comments
Assignees

Comments

@weexp
Copy link

weexp commented Jun 25, 2015

Hi vrogier,
When I use function OCI_CollFree(), I find it does not work well. I check the source code, in the file
collection.c : line 147:
/* free data element /
if (coll->elem)
{
coll->elem->hstate = OCI_OBJECT_FETCHED_DIRTY;
OCI_ElemFree(coll->elem);
coll->elem = NULL;
}
I guess the coll handle only free one elem, not free all elem in the collection, it may lead to memory leak.
I write some sample code like this:
OCI_Object
GEOMETRY = NULL;
OCI_TypeInfo* obj_type = OCI_TypeInfoGet(connection, "MDSYS.SDO_GEOMETRY", OCI_TIF_TYPE);
OCI_TypeInfo* coll_type = OCI_TypeInfoGet(connection, "MDSYS.SDO_ORDINATE_ARRAY", OCI_TIF_TYPE);
while(1)
{
OCI_Coll* sdo_ordinate_array = OCI_CollCreate(coll_type);
OCI_CollFree(sdo_ordinate_array);
}

   Memory leak happens.
  I suggest the source code maybe modify like this:
    /* free data element */

for(int i = 0; i < OCI_CollGetSize(coll); ++i)
{
OCI_Elem elem = OCI_CollGetElem(coll,i);
if (elem)
{
elem ->hstate = OCI_OBJECT_FETCHED_DIRTY;
OCI_ElemFree(elem);
elem = NULL;
}
}

@vrogier
Copy link
Owner

vrogier commented Jun 25, 2015

Hi,

Can you provide a working sample code that demonstrate the leak ?

Thanks

@vrogier vrogier changed the title problem in OCI_CollFree Problem in OCI_CollFree Jun 25, 2015
@vrogier vrogier changed the title Problem in OCI_CollFree Problem in OCI_CollFree() Jun 25, 2015
@vrogier vrogier self-assigned this Jun 25, 2015
@weexp
Copy link
Author

weexp commented Jun 25, 2015

My test Code just like this:
void testOcilib(std::string db_url, std::string user_name, std::string pass_word, std::string TableName)
{

OCI_Connection* connection = 0;
OCI_Transaction* transaction = 0;
OCI_Statement* statement = 0;
OCI_Resultset* results = 0;

int isSus = OCI_Initialize(0, 0, OCI_ENV_CONTEXT);
connection = OCI_ConnectionCreate(db_url.c_str(), user_name.c_str(), pass_word.c_str(), OCI_SESSION_DEFAULT);
transaction = OCI_TransactionCreate(connection, 1, OCI_TRS_NEW, 0);
statement = OCI_StatementCreate(connection);

OCI_TypeInfo* obj_type = OCI_TypeInfoGet(connection, "MDSYS.SDO_GEOMETRY", OCI_TIF_TYPE);
OCI_TypeInfo* coll_type = OCI_TypeInfoGet(connection, "MDSYS.SDO_ORDINATE_ARRAY", OCI_TIF_TYPE);
while(1)
{
    OCI_Coll* sdo_ordinate_array = OCI_CollCreate(coll_type);
    OCI_CollFree(sdo_ordinate_array);
}
//transaction
if (0 != transaction)
{
    OCI_TransactionFree(transaction);
    transaction = 0;
}
//statement
if (0 != statement)
{
    OCI_StatementFree(statement);
    statement = 0;
}
//connection
if (0 != connection)
{
    OCI_ConnectionFree(connection);
    connection = 0;
}
OCI_Cleanup();

return ;

}

VS2010 platform, oracle 11g, OCI_CHARSET_ANSI

@vrogier
Copy link
Owner

vrogier commented Jun 25, 2015

Thanks.

I will check the issue asap

@vrogier
Copy link
Owner

vrogier commented Jun 25, 2015

Hi,

There is no memroy leak but rather memory retention (the memory is freed when calling OCI_Cleanup().
When the collection is freed, OCILIB call the oracle method OCIObjectFree() on the collection handle with the flag OCI_OBJECTFREE_NONULL.
The OCI client is maintaining a local cache of objects. with your code, it seems that is does not reuse previously allocated object as it should. Replacing the flag OCI_OBJECTFREE_NONULL by OCI_OBJECTFREE_FORCE forces the cleanup of the object instead of maintaining it in the cache.
And you code sample runs with constant memory.
I will study the impact of changing the flag and may commit it if there is no issue with it.

Regards,

Vincent

@vrogier
Copy link
Owner

vrogier commented Jun 25, 2015

In fact, after having checked again Oracle documentation, it appears that OCILIB should not use the flag OCI_OBJECTFREE_NONULL but rather pass OCI_DEFAULT. Nothing to do with OCI_OBJECTFREE_FORCE.
With OCI_OBJECTFREE_NONULL , the object indicator structure is not freed !

i will commit a fix for that these evening !

@vrogier
Copy link
Owner

vrogier commented Jun 25, 2015

Fix committed :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants