Thread: ECPG: FETCH ALL|n FROM cursor - Memory allocation?
Assuming the following fetch statement in embedded SQL/C: EXEC SQL FETCH ALL IN selectFromTable_cur INTO:array1,:array2; is memory automatically allocated (by experimentation I guess so)? Should the input pointers be NULL initialised? How should the memory be freed? Assuming the following fetch statement: while( 1 ){ EXEC SQL FETCH 1000 IN selectFromTable_cur INTO :array1, :array2; if( (sqlca.sqlcode < 0) || (sqlca.sqlcode !=0) ) break;} is memory automatically allocated (by experimentation I guess so)? Should the input pointers be NULL initialised before each fetch, or only before the first one? How should the memory be freed? Any pointers to useful documentation? Thanks, Lee Kindness.
On Thu, Apr 25, 2002 at 12:42:00PM +0100, Lee Kindness wrote: > Assuming the following fetch statement in embedded SQL/C: > > EXEC SQL FETCH ALL IN selectFromTable_cur INTO > :array1, > :array2; > > is memory automatically allocated (by experimentation I guess so)? Only if the pointers are NULL. If they have a value libecpg assumes that this value points to enough memory to store all data. > Should the input pointers be NULL initialised? How should the memory > be freed? A simple free() will do. You also can free all automatically allocated memory from the most recent executed statement by calling ECPGfree_auto_mem(). But this is not documented and will never be. The correct way is to free(array1) and free(array2) while libecpg will free the internal structures when the next statement is executed. Michael -- Michael Meskes Michael@Fam-Meskes.De Go SF 49ers! Go Rhein Fire! Use Debian GNU/Linux! Use PostgreSQL!
Michael Meskes wrote: > On Thu, Apr 25, 2002 at 12:42:00PM +0100, Lee Kindness wrote: >>Should the input pointers be NULL initialised? How should the memory >>be freed? > > > A simple free() will do. You also can free all automatically > allocated memory from the most recent executed statement by calling > ECPGfree_auto_mem(). But this is not documented and will never be. > > The correct way is to free(array1) and free(array2) while libecpg will > free the internal structures when the next statement is executed. Never, never mix these two! ECPGfree_auto_mem will free even memory which has already been free'd by the user, perhaps we should get rid of this method (any allocated memory regions are stored in a list, if you never call ECPGfree_auto_mem, this list grows and grows). Christof
Okay, lets see if i've got this right... If I allocate the memory before the FETCH then I (naturally) free it. However If I NULL initialise the pointer then libecpg will allocate the memory and I must NOT free it - libecpg will free it automatically... Yeah? I think this highlights the need for some documentation on this aspect. Regards, Lee Kindness. Christof Petig writes:> Michael Meskes wrote:> > On Thu, Apr 25, 2002 at 12:42:00PM +0100, Lee Kindness wrote:> >>Shouldthe input pointers be NULL initialised? How should the memory> >>be freed?> > > > > > A simple free() will do. Youalso can free all automatically> > allocated memory from the most recent executed statement by calling> > ECPGfree_auto_mem().But this is not documented and will never be.> > > > The correct way is to free(array1) and free(array2)while libecpg will> > free the internal structures when the next statement is executed.> > Never, never mix thesetwo! ECPGfree_auto_mem will free even memory > which has already been free'd by the user, perhaps we should get ridof > this method (any allocated memory regions are stored in a list, if you > never call ECPGfree_auto_mem, this listgrows and grows).> > Christof>
On Mon, May 06, 2002 at 09:37:18AM +0200, Christof Petig wrote: > Never, never mix these two! ECPGfree_auto_mem will free even memory > which has already been free'd by the user, perhaps we should get rid of That's why I discourage the usage of ECPGfree_auto_mem by the user. There is only one reason why the symbol is not static and that is that it is used by another module in libecpg. I never thought about this as an end user routine, it's just meant as a clean up method in case of an error during statement execution. BTW Christof, ECPGfree_auto_mem is used by testdynalloc.pgc. Maybe we should change that. > this method (any allocated memory regions are stored in a list, if you > never call ECPGfree_auto_mem, this list grows and grows). That is not true. Before a statement is executed libecpg calls ECPGclear_auto_mem which just frees ecpg's own structure but not the memory used for data. Michael -- Michael Meskes Michael@Fam-Meskes.De Go SF 49ers! Go Rhein Fire! Use Debian GNU/Linux! Use PostgreSQL!
On Mon, May 06, 2002 at 11:24:36AM +0100, Lee Kindness wrote: > If I allocate the memory before the FETCH then I (naturally) free > it. However If I NULL initialise the pointer then libecpg will > allocate the memory and I must NOT free it - libecpg will free it > automatically... Yeah? No. No matter who allocates the memory. You have to free it yourself. Michael -- Michael Meskes Michael@Fam-Meskes.De Go SF 49ers! Go Rhein Fire! Use Debian GNU/Linux! Use PostgreSQL!
Lee Kindness wrote: > Okay, lets see if i've got this right... > > If I allocate the memory before the FETCH then I (naturally) free > it. However If I NULL initialise the pointer then libecpg will > allocate the memory and I must NOT free it - libecpg will free it > automatically... Yeah? No, I only said: Never mix free and ECPGfree_auto_mem because ECPGfree_auto_mem will double free it if you free'd it already. And also: it might be a good idea to kill the undocumented function (and the list). And: You need to free it (by one of the two methods above). > > I think this highlights the need for some documentation on this > aspect. Yes it does. Christof
Michael Meskes wrote: > On Thu, Apr 25, 2002 at 12:42:00PM +0100, Lee Kindness wrote: >>Should the input pointers be NULL initialised? How should the memory >>be freed? > > > A simple free() will do. You also can free all automatically > allocated memory from the most recent executed statement by calling > ECPGfree_auto_mem(). But this is not documented and will never be. > > The correct way is to free(array1) and free(array2) while libecpg will > free the internal structures when the next statement is executed. Never, never mix these two! ECPGfree_auto_mem will free even memory which has already been free'd by the user, perhaps we should get rid of this method (any allocated memory regions are stored in a list, if you never call ECPGfree_auto_mem, this list grows and grows). Christof