]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Publish APIs sqlite3_malloc() and sqlite3_realloc() that use the OS-layer
authordrh <drh@noemail.net>
Mon, 26 Jun 2006 21:35:44 +0000 (21:35 +0000)
committerdrh <drh@noemail.net>
Mon, 26 Jun 2006 21:35:44 +0000 (21:35 +0000)
memory allocator.  Convert sqlite3_free() and sqlite3_mprintf() to also
use the OS-layer memory allocator. (CVS 3298)

FossilOrigin-Name: 85a66a25e97471d3c459c8da6a96990b0537dc7d

13 files changed:
manifest
manifest.uuid
src/legacy.c
src/loadext.c
src/main.c
src/printf.c
src/sqlite.h.in
src/sqlite3ext.h
src/sqliteInt.h
src/table.c
src/test3.c
test/loadext.test
www/capi3ref.tcl

index 1b250ac4e4f7217c16d7dc31bae44a21a59b78fa..d5d17005609197d0b0fc3241be0199bba15aebce 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Remove\sthe\ssqlite3_module.zName\sfield\swhich\swas\sused\sonly\sfor\sdebugging.\s(CVS\s3297)
-D 2006-06-26T19:10:32
+C Publish\sAPIs\ssqlite3_malloc()\sand\ssqlite3_realloc()\sthat\suse\sthe\sOS-layer\nmemory\sallocator.\s\sConvert\ssqlite3_free()\sand\ssqlite3_mprintf()\sto\salso\nuse\sthe\sOS-layer\smemory\sallocator.\s(CVS\s3298)
+D 2006-06-26T21:35:45
 F Makefile.in f839b470345d3cb4b0644068474623fe2464b5d3
 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -47,9 +47,9 @@ F src/func.c f357a81bcdd83684cb198a8ad96be1c21e29f85c
 F src/hash.c 449f3d6620193aa557f5d86cbc5cc6b87702b185
 F src/hash.h 1b3f7e2609141fd571f62199fc38687d262e9564
 F src/insert.c 63f01d3f4e0ba7ed171934a24aece2191824faec
-F src/legacy.c fa15d505dd4e45044177ee4d1c6aeaf8c836d390
-F src/loadext.c b08c5f5a57b78afd8cd0dd1677e98519e18db56f
-F src/main.c b71877c9c3cd491417fc7d4bbc785ddab411034c
+F src/legacy.c 10e01a902d7f2c872c7922fedf19a2df70935857
+F src/loadext.c 66035906cd0ea9904eb70884a41116f41a957bc9
+F src/main.c 2f78bd86852fdd42e3e9e0e4dba54000d9dc516d
 F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
 F src/os.c 59f05de8c5777c34876607114a2fbe55ae578235
 F src/os.h 3fd6a022bafd620fdfd779a51dccb42f31c97f75
@@ -67,19 +67,19 @@ F src/pager.h 43f32f3847421f7502cfbb66f4eb2302b8033818
 F src/parse.y e0831a269fbbd21414bb367fd0b806569c934683
 F src/pragma.c 27d5e395c5d950931c7ac4fe610e7c2993e2fa55
 F src/prepare.c e477df44112e3ce167f048226432fca9d9cba6a0
-F src/printf.c 7029e5f7344a478394a02c52837ff296ee1ab240
+F src/printf.c b179b6ed12f793e028dd169e2e2e2b2a37eedc63
 F src/random.c d40f8d356cecbd351ccfab6eaedd7ec1b54f5261
 F src/select.c 380fa06c99ae01050c0054c4b1db91e9f1d8322d
 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
 F src/shell.c ad73192b30a338a58fe81183d4a5d5a1d4e51d36
-F src/sqlite.h.in a60bbe9571428b0ae492335765de634905036742
-F src/sqlite3ext.h e334107f6cad0d00c0414e04189742a45ce916b1
-F src/sqliteInt.h a2bef52ecec0be7e56b88d82a514df7fe4863767
-F src/table.c f64ec4fbfe333f8df925bc6ba494f55e05b0e75e
+F src/sqlite.h.in af0ec0cfb2f8211e42cabf2523d1c8783f35ccaf
+F src/sqlite3ext.h 106a003c825c16bd100a1eed8c047a41e7bb2c4c
+F src/sqliteInt.h 4b1a3193b875a4d56f07be87eb97d5014617fe60
+F src/table.c e707e822aad688034d391b93df63d6b2d302fdca
 F src/tclsqlite.c 32d9e0147077f2e2c127c5f214fb3fe03ef97d18
 F src/test1.c 233d5c83d11f34aa1c02eb72011ba9a30b72e078
 F src/test2.c ca74a1d8aeb7d9606e8f6b762c5daf85c1a3f92b
-F src/test3.c 86e99724ee898b119ed575ef9f98618afe7e5e5d
+F src/test3.c 833dc8346e431182ae6bd0648455c3d4cc65a19f
 F src/test4.c 8b784cd82de158a2317cb4ac4bc86f91ad315e25
 F src/test5.c 7162f8526affb771c4ed256826eee7bb9eca265f
 F src/test6.c 60a02961ceb7b3edc25f5dc5c1ac2556622a76de
@@ -196,7 +196,7 @@ F test/lastinsert.test 474d519c68cb79d07ecae56a763aa7f322c72f51
 F test/laststmtchanges.test 19a6d0c11f7a31dc45465b495f7b845a62cbec17
 F test/like.test 5f7d76574752a9101cac13372c8a85999d0d91e6
 F test/limit.test 2a87b9cb2165abb49ca0ddcf5cb43cf24074581f
-F test/loadext.test c5790632f1ae974e8c01d43c859a56bb8c08ded6
+F test/loadext.test 6a047b9bb784a92643c371643bf8acf29a0beb6e
 F test/lock.test 9b7afcb24f53d24da502abb33daaad2cd6d44107
 F test/lock2.test d83ba79d3c4fffdb5b926c7d8ca7a36c34288a55
 F test/lock3.test 615111293cf32aa2ed16d01c6611737651c96fb9
@@ -330,7 +330,7 @@ F www/audit.tcl 90e09d580f79c7efec0c7d6f447b7ec5c2dce5c0
 F www/autoinc.tcl b357f5ba954b046ee35392ce0f884a2fcfcdea06
 F www/c_interface.tcl b51b08591554c16a0c3ef718364a508ac25abc7e
 F www/capi3.tcl 7a7cc225fe02eb7ab861a6019b08baa0014409e1
-F www/capi3ref.tcl 530fffe3b5729981dc4cfd32e2bafd4ba3dad2ec
+F www/capi3ref.tcl de1db9415d6ac5908cad436ce4598eba8f536c4a
 F www/changes.tcl ec6d4fa4d302a76d662509c7c4796a159bd66b31
 F www/common.tcl 14d121c28532ad20c3e349caa4db708b0b822083
 F www/compile.tcl 276546d7eb445add5a867193bbd80f6919a6b084
@@ -374,7 +374,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P 6a63f76c8de977b628c4cab258be5a11d7d7def9
-R 13217c648df812862d4f04bedcadf8ca
+P 74a3961f39b9a045518835b20940471ac97bca66
+R 694275a07db1c279baabcfc8350ecbab
 U drh
-Z 7d581b1a7871f427abdbb3e24fd87b75
+Z aba47820684b05583eb21c2e0f904679
index 5559a73ac5ee9e0484fcfc5003a8af2cc5e8f343..59753209599b49d1496b7c5a0cf8a33ad0aa7370 100644 (file)
@@ -1 +1 @@
-74a3961f39b9a045518835b20940471ac97bca66
\ No newline at end of file
+85a66a25e97471d3c459c8da6a96990b0537dc7d
\ No newline at end of file
index d724e8a428208a52d3c1cb03d9ade833f22a3706..39e1361face8453ee81adba972c0bbf3d3d4f8a0 100644 (file)
@@ -14,7 +14,7 @@
 ** other files are for internal use by SQLite and should not be
 ** accessed by users of the library.
 **
-** $Id: legacy.c,v 1.14 2006/03/06 20:55:46 drh Exp $
+** $Id: legacy.c,v 1.15 2006/06/26 21:35:45 drh Exp $
 */
 
 #include "sqliteInt.h"
@@ -123,7 +123,7 @@ exec_out:
 
   rc = sqlite3ApiExit(0, rc);
   if( rc!=SQLITE_OK && rc==sqlite3_errcode(db) && pzErrMsg ){
-    *pzErrMsg = malloc(1+strlen(sqlite3_errmsg(db)));
+    *pzErrMsg = sqlite3_malloc(1+strlen(sqlite3_errmsg(db)));
     if( *pzErrMsg ){
       strcpy(*pzErrMsg, sqlite3_errmsg(db));
     }
index 71eb89bd3dc3086eb773042f5e42957a67d4d0fc..6b277675f1736751cd6a7afe394a8daa7d31383e 100644 (file)
@@ -157,6 +157,7 @@ const sqlite3_api_routines sqlite3_api = {
   sqlite3_last_insert_rowid,
   sqlite3_libversion,
   sqlite3_libversion_number,
+  sqlite3_malloc,
   sqlite3_mprintf,
   sqlite3_open,
   sqlite3_open16,
@@ -164,6 +165,7 @@ const sqlite3_api_routines sqlite3_api = {
   sqlite3_prepare16,
   sqlite3_profile,
   sqlite3_progress_handler,
+  sqlite3_realloc,
   sqlite3_reset,
   sqlite3_result_blob,
   sqlite3_result_double,
index 6a5cac3217edfa5668ec416fac605eeefabed61a..c5d50bd50ba53e748a3f71815e13e54ae24dc7a0 100644 (file)
@@ -14,7 +14,7 @@
 ** other files are for internal use by SQLite and should not be
 ** accessed by users of the library.
 **
-** $Id: main.c,v 1.348 2006/06/24 11:51:33 danielk1977 Exp $
+** $Id: main.c,v 1.349 2006/06/26 21:35:45 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -385,14 +385,29 @@ void sqlite3_interrupt(sqlite3 *db){
 }
 
 /*
-** Windows systems should call this routine to free memory that
-** is returned in the in the errmsg parameter of sqlite3_open() when
-** SQLite is a DLL.  For some reason, it does not work to call free()
-** directly.
+** Memory allocation routines that use SQLites internal memory
+** memory allocator.  Depending on how SQLite is compiled, the
+** internal memory allocator might be just an alias for the
+** system default malloc/realloc/free.  Or the built-in allocator
+** might do extra stuff like put sentinals around buffers to 
+** check for overruns or look for memory leaks.
 **
-** Note that we need to call free() not sqliteFree() here.
+** Use sqlite3_free() to free memory returned by sqlite3_mprintf().
 */
-void sqlite3_free(char *p){ free(p); }
+void sqlite3_free(void *p){ if( p ) sqlite3OsFree(p); }
+void *sqlite3_malloc(int nByte){ return nByte>0 ? sqlite3OsMalloc(nByte) : 0; }
+void *sqlite3_realloc(void *pOld, int nByte){ 
+  if( pOld ){
+    if( nByte>0 ){
+      return sqlite3OsRealloc(pOld, nByte);
+    }else{
+      sqlite3OsFree(pOld);
+      return 0;
+    }
+  }else{
+    return sqlite3_malloc(nByte);
+  }
+}
 
 /*
 ** This function is exactly the same as sqlite3_create_function(), except
index 7e62c9c38197692dcf3da869302ac870ef1106ee..b4c37fb61de51a8918ae202b5c31cacfcc29776a 100644 (file)
@@ -806,29 +806,28 @@ char *sqlite3MPrintf(const char *zFormat, ...){
 }
 
 /*
-** Print into memory obtained from malloc().  Do not use the internal
-** %-conversion extensions.  This routine is for use by external users.
+** Print into memory obtained from sqlite3_malloc().  Omit the internal
+** %-conversion extensions.
+*/
+char *sqlite3_vmprintf(const char *zFormat, va_list ap){
+  char zBase[SQLITE_PRINT_BUF_SIZE];
+  return base_vprintf(sqlite3_realloc, 0, zBase, sizeof(zBase), zFormat, ap);
+}
+
+/*
+** Print into memory obtained from sqlite3_malloc()().  Omit the internal
+** %-conversion extensions.
 */
 char *sqlite3_mprintf(const char *zFormat, ...){
   va_list ap;
   char *z;
-  char zBuf[200];
-
-  va_start(ap,zFormat);
-  z = base_vprintf((void*(*)(void*,int))realloc, 0, 
-                   zBuf, sizeof(zBuf), zFormat, ap);
+  char zBase[SQLITE_PRINT_BUF_SIZE];
+  va_start(ap, zFormat);
+  z = base_vprintf(sqlite3_realloc, 0, zBase, sizeof(zBase), zFormat, ap);
   va_end(ap);
   return z;
 }
 
-/* This is the varargs version of sqlite3_mprintf.  
-*/
-char *sqlite3_vmprintf(const char *zFormat, va_list ap){
-  char zBuf[200];
-  return base_vprintf((void*(*)(void*,int))realloc, 0,
-                      zBuf, sizeof(zBuf), zFormat, ap);
-}
-
 /*
 ** sqlite3_snprintf() works like snprintf() except that it ignores the
 ** current locale settings.  This is important for SQLite because we
index de2fcdc7c96f53f9e88b42ecbcc9f8ce107244d0..86876555f38570290ecc2b652631d31f0820c3fa 100644 (file)
@@ -12,7 +12,7 @@
 ** This header file defines the interface that the SQLite library
 ** presents to client programs.
 **
-** @(#) $Id: sqlite.h.in,v 1.183 2006/06/26 19:10:32 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.184 2006/06/26 21:35:45 drh Exp $
 */
 #ifndef _SQLITE3_H_
 #define _SQLITE3_H_
@@ -405,9 +405,19 @@ void sqlite3_free_table(char **result);
 */
 char *sqlite3_mprintf(const char*,...);
 char *sqlite3_vmprintf(const char*, va_list);
-void sqlite3_free(char *z);
 char *sqlite3_snprintf(int,char*,const char*, ...);
 
+/*
+** SQLite uses its own memory allocator.  On many installations, this
+** memory allocator is identical to the standard malloc()/realloc()/free()
+** and can be used interchangable.  On others, the implementations are
+** different.  For maximum portability, it is best not to mix calls
+** to the standard malloc/realloc/free with the sqlite versions.
+*/
+void *sqlite3_malloc(int);
+void *sqlite3_realloc(void*, int);
+void sqlite3_free(void*);
+
 #ifndef SQLITE_OMIT_AUTHORIZATION
 /*
 ** This routine registers a callback with the SQLite library.  The
index a1ed67f86ee5c9561f78620ee9ecffd8c058b946..5088499da39e28ba887f6237423b484978066968 100644 (file)
@@ -15,7 +15,7 @@
 ** as extensions by SQLite should #include this file instead of 
 ** sqlite3.h.
 **
-** @(#) $Id: sqlite3ext.h,v 1.3 2006/06/16 21:13:22 drh Exp $
+** @(#) $Id: sqlite3ext.h,v 1.4 2006/06/26 21:35:45 drh Exp $
 */
 #ifndef _SQLITE3EXT_H_
 #define _SQLITE3EXT_H_
@@ -95,6 +95,7 @@ struct sqlite3_api_routines {
   sqlite_int64  (*last_insert_rowid)(sqlite3*);
   const char * (*libversion)(void);
   int  (*libversion_number)(void);
+  void *(*malloc)(int);
   char * (*mprintf)(const char*,...);
   int  (*open)(const char*,sqlite3**);
   int  (*open16)(const void*,sqlite3**);
@@ -102,6 +103,7 @@ struct sqlite3_api_routines {
   int  (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
   void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*);
   void  (*progress_handler)(sqlite3*,int,int(*)(void*),void*);
+  void *(*realloc)(void*,int);
   int  (*reset)(sqlite3_stmt*pStmt);
   void  (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*));
   void  (*result_double)(sqlite3_context*,double);
@@ -221,6 +223,7 @@ struct sqlite3_api_routines {
 #define sqlite3_last_insert_rowid      sqlite3_api->last_insert_rowid
 #define sqlite3_libversion             sqlite3_api->libversion
 #define sqlite3_libversion_number      sqlite3_api->libversion_number
+#define sqlite3_malloc                 sqlite3_api->malloc
 #define sqlite3_mprintf                sqlite3_api->mprintf
 #define sqlite3_open                   sqlite3_api->open
 #define sqlite3_open16                 sqlite3_api->open16
@@ -228,6 +231,7 @@ struct sqlite3_api_routines {
 #define sqlite3_prepare16              sqlite3_api->prepare16
 #define sqlite3_profile                sqlite3_api->profile
 #define sqlite3_progress_handler       sqlite3_api->progress_handler
+#define sqlite3_realloc                sqlite3_api->realloc
 #define sqlite3_reset                  sqlite3_api->reset
 #define sqlite3_result_blob            sqlite3_api->result_blob
 #define sqlite3_result_double          sqlite3_api->result_double
index f49de42d3ab4cd0941f9d233eff20a4b3ab922ef..f973254c84ba4d7c5c8ae38320c0a499fce732cf 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.513 2006/06/26 19:10:32 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.514 2006/06/26 21:35:45 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
index 8bd9ea71fb3773ffeaf55e441053accbebff7232..5c99c523f23b0dcb8c4a0d32e2cd5633bbb9cce1 100644 (file)
@@ -59,7 +59,7 @@ static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
   if( p->nData + need >= p->nAlloc ){
     char **azNew;
     p->nAlloc = p->nAlloc*2 + need + 1;
-    azNew = realloc( p->azResult, sizeof(char*)*p->nAlloc );
+    azNew = sqlite3_realloc( p->azResult, sizeof(char*)*p->nAlloc );
     if( azNew==0 ) goto malloc_failed;
     p->azResult = azNew;
   }
@@ -73,7 +73,7 @@ static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
       if( colv[i]==0 ){
         z = 0;
       }else{
-        z = malloc( strlen(colv[i])+1 );
+        z = sqlite3_malloc( strlen(colv[i])+1 );
         if( z==0 ) goto malloc_failed;
         strcpy(z, colv[i]);
       }
@@ -94,7 +94,7 @@ static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
       if( argv[i]==0 ){
         z = 0;
       }else{
-        z = malloc( strlen(argv[i])+1 );
+        z = sqlite3_malloc( strlen(argv[i])+1 );
         if( z==0 ) goto malloc_failed;
         strcpy(z, argv[i]);
       }
@@ -140,7 +140,7 @@ int sqlite3_get_table(
   res.nData = 1;
   res.nAlloc = 20;
   res.rc = SQLITE_OK;
-  res.azResult = malloc( sizeof(char*)*res.nAlloc );
+  res.azResult = sqlite3_malloc( sizeof(char*)*res.nAlloc );
   if( res.azResult==0 ) return SQLITE_NOMEM;
   res.azResult[0] = 0;
   rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg);
@@ -152,7 +152,7 @@ int sqlite3_get_table(
     sqlite3_free_table(&res.azResult[1]);
     if( res.zErrMsg ){
       if( pzErrMsg ){
-        free(*pzErrMsg);
+        sqlite3_free(*pzErrMsg);
         *pzErrMsg = sqlite3_mprintf("%s",res.zErrMsg);
       }
       sqliteFree(res.zErrMsg);
@@ -167,7 +167,7 @@ int sqlite3_get_table(
   }
   if( res.nAlloc>res.nData ){
     char **azNew;
-    azNew = realloc( res.azResult, sizeof(char*)*(res.nData+1) );
+    azNew = sqlite3_realloc( res.azResult, sizeof(char*)*(res.nData+1) );
     if( azNew==0 ){
       sqlite3_free_table(&res.azResult[1]);
       return SQLITE_NOMEM;
@@ -192,8 +192,8 @@ void sqlite3_free_table(
     azResult--;
     if( azResult==0 ) return;
     n = (int)azResult[0];
-    for(i=1; i<n; i++){ if( azResult[i] ) free(azResult[i]); }
-    free(azResult);
+    for(i=1; i<n; i++){ if( azResult[i] ) sqlite3_free(azResult[i]); }
+    sqlite3_free(azResult);
   }
 }
 
index bd0ff8a960999e710176d1426dc0ea9117af3dcc..3d4c086f24f3075d13c2d8f941279c67354672de 100644 (file)
@@ -13,7 +13,7 @@
 ** is not included in the SQLite library.  It is used for automated
 ** testing of the SQLite library.
 **
-** $Id: test3.c,v 1.65 2006/01/20 10:55:05 danielk1977 Exp $
+** $Id: test3.c,v 1.66 2006/06/26 21:35:46 drh Exp $
 */
 #include "sqliteInt.h"
 #include "pager.h"
@@ -585,6 +585,7 @@ static int btree_integrity_check(
 #else
   zResult = 0;
 #endif
+  free(aRoot);
   if( zResult ){
     Tcl_AppendResult(interp, zResult, 0);
     sqliteFree(zResult); 
index ba0d2f87d157c581410be01f68680a7d69a2fd81..b53e8bad62fa7a7555a8ea281beb799e5c5115d2 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this script is in-memory database backend.
 #
-# $Id: loadext.test,v 1.3 2006/06/17 14:12:48 drh Exp $
+# $Id: loadext.test,v 1.4 2006/06/26 21:35:46 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -32,7 +32,7 @@ if {![file exists $testextension]} {
   set srcdir [file dir $testdir]/src
   set testextsrc $srcdir/test_loadext.c
   if {[catch {
-    exec gcc -shared $testextsrc -o $testextension
+    exec gcc -Wall -g -shared $testextsrc -o $testextension
   } msg]} {
     puts "Skipping loadext tests: Test extension not built..."
     puts $msg
index a897a863e0971f00406bcd150b2e4dbc5ca492ff..1434b146ddd1fd707e6e89161a79be2aebe10b17 100644 (file)
@@ -1,4 +1,4 @@
-set rcsid {$Id: capi3ref.tcl,v 1.40 2006/06/14 15:35:37 drh Exp $}
+set rcsid {$Id: capi3ref.tcl,v 1.41 2006/06/26 21:35:46 drh Exp $}
 source common.tcl
 header {C/C++ Interface For SQLite Version 3}
 puts {
@@ -826,10 +826,36 @@ int sqlite3_finalize(sqlite3_stmt *pStmt);
 }
 
 api {} {
-void sqlite3_free(char *z);
+void *sqlite3_malloc(int);
+void *sqlite3_realloc(void*, int);
+void sqlite3_free(void*);
 } {
- Use this routine to free memory obtained from 
- sqlite3_mprintf() or sqlite3_vmprintf().
+ These routines provide access to the memory allocator used by SQLite.
+ Depending on how SQLite has been compiled and the OS-layer backend,
+ the memory allocator used by SQLite might be the standard system
+ malloc()/realloc()/free(), or it might be something different.  With
+ certain compile-time flags, SQLite will add wrapper logic around the
+ memory allocator to add memory leak and buffer overrun detection.  The
+ OS layer might substitute a completely different memory allocator.
+ Use these APIs to be sure you are always using the correct memory
+ allocator.
+ The sqlite3_free() API, not the standard free() from the system library,
+ should always be used to free the memory buffer returned by
+ sqlite3_mprintf() or sqlite3_vmprintf() and to free the error message
+ string returned by sqlite3_exec().  Using free() instead of sqlite3_free()
+ might accidentally work on some systems and build configurations but 
+ will fail on others.
+
+ Compatibility Note:  Prior to version 3.4.0, the sqlite3_free API
+ was prototyped to take a <tt>char*</tt> parameter rather than 
+ <tt>void*</tt>.  Like this:
+<blockquote><pre>
+void sqlite3_free(char*);
+</pre></blockquote>
+ The change to using <tt>void*</tt> might cause warnings when 
+ compiling older code against
+ newer libraries, but everything should still work correctly.
 }
 
 api {} {