D. Richard Hipp wrote:
On Wed, 2005-06-29 at 15:19 +0300, Lauri Nurmi wrote:
So, basically, is there a reason why sqlite3Malloc(n) & co should even
try to allocate zero bytes, instead of just returning NULL if n==0? Does
a pointer pointing to zero bytes of memory have any use anyway?
Yes. A NULL return from sqlite3Malloc() is an error condition meaning
that you have run out of memory. That is very different from returning
a zero-length memory allocation.
Richard,
I don' t believe that this is true. In the source for sqlite3Malloc()
you do an explicit check for a requested size of 0 and return zero
without calling the library malloc function. So you will return NULL for
this case even if there is plenty of memory left. A NULL return does not
mean out of memory.
The code of concern is in sqlite3_exec where you allocate zero bytes for
a statement that has no result columns. Here you follow the allocation
with an explicit check that the number of requested bytes was non-zero
AND the allocated memory pointer is NULL before you declare an out of
memory error.
This code appears to be safe since the azCol buffer is only referenced
if the number of result columns is greater than zero (except where it is
released, but freeing a NULL pointer is supposed to be safe, though
there are systems where this can be problematic), so the allocation
should always be valid or correctly generate an out of memory error.
It might be clearer to separate the check for the number of result
columns and only do the allocation if it is greater than 0. This will
leave the azCol pointer with its initialized value of 0 if there are no
results. You could replace:
azCols = sqliteMalloc(2*nCol*sizeof(const char *));
if( nCol && !azCols ){
rc = SQLITE_NOMEM;
goto exec_out;
}
with
if( nCol > 0 ){
azCols = sqliteMalloc(2*nCol*sizeof(const char *));
if( !azCols ){
rc = SQLITE_NOMEM;
goto exec_out;
}
}
This would save a subroutine call and the checks in sqlite3Malloc for
the common case of users using sqlite3_exec() for statments such as
"BEGIN TRANSACTION". Admittedly, this is a very small performance gain.
Dennis Cote