缺省内存分配器(mem1.c)
这个文件包含了底层内存分配器,该分配器包含了标准的C函数库,比如malloc/realloc/free接口。当既没有定义SQLITE_MEMDEBUG,也没有定义SQLITE_WIN32_MALLOC时,SQLITE_WIN32_MALLOC被自动定义。
文件中包含的预处理宏:
HAVE_MALLOC_USABLE_SIZE
SQLITE_WITHOUT_ZONEMALLOC
SQLITE_WITHOUT_MSIZE
特征:
SQLITE_SYSTEM_MALLOC; 定义该分配器的宏。- 在每个
malloc()分配的头部,多分配8byte保存分配的大小,以使用memsize()返回当前分配的大小; memsize()还可跟踪未归还的内存字节数,它能确定当一个分配被释放时,能有多少内存从未归还的内存中移除;- 在大多数的应用程序中建议都使用这个缺省的内存分配器。
函数介绍
| 编号 | 函数名 | 功能 |
|---|---|---|
| 1 | static void *sqlite3MemMalloc(int nByte) | 分配一块长度为nByte字节的连续区域 |
| 2 | static void sqlite3MemFree(void *pPrior) | 释放pPrior指向的存储空间 |
| 3 | static int sqlite3MemSize(void *pPrior) | 返回已分配内存的大小 |
| 4 | static void *sqlite3MemRealloc(void *pPrior, int nByte) | 给一个已经分配了地址的指针重新分配空间 |
| 5 | static int sqlite3MemRoundup(int n) | 舍入到下一个有效内存分配的大小。 |
| 6 | static int sqlite3MemInit(void *NotUsed) | 函数初始化 |
| 7 | static void sqlite3MemShutdown(void *NotUsed) | 取消函数的初始化 |
| 8 | void sqlite3MemSetDefault(void) | 底层内存分配函数 |
主要函数介绍
初始化函数static int sqlite3MemInit(void *NotUsed)
初始化根据不同的平台,采用不同的操作。
分配函数static void *sqlite3MemMalloc(int nByte)
该函数根据宏定义决定是否多分配8字节的头部来记录本次分配的大小,分配函数直接调用系统的malloc函数。在返回的时候,返回的指针是指向分配内存头部(记录大小)的下一个字节。执行流程如下:
释放函数static void sqlite3MemFree(void *pPrior)
根据宏定义的不同,采取不同的释放动作,若定义了宏,则直接释放,否则找到内存空间头部的地址(p--),然后在释放,释放函数采用free。
调整内存大小static void *sqlite3MemRealloc(void *pPrior, int nByte)
若定义了宏,直接利用realloc函数调整,没有定义则利用realloc函数调整,再多分配8byte的头部,最后移动指针,返回调整后内存空间的地址。
返回内存大小static int sqlite3MemSize(void *pPrior)
若定义了宏,则直接返回指着所指内存区域的大小,否则,返回内存区域头部的值,即除去头部大小的值。
函数测试
分配函数
mem1 test
分配内存...
分配内存的大小为:1024
释放内存...
a.out: mem1.c:51: sqlite3MemFree: Assertion `pPrior!=0' failed.
==37156==
==37156== Process terminating with default action of signal 6 (SIGABRT)
==37156== at 0x4E6B5F7: raise (in /usr/lib64/libc-2.17.so)
==37156== by 0x4E6CCE7: abort (in /usr/lib64/libc-2.17.so)
==37156== by 0x4E64565: __assert_fail_base (in /usr/lib64/libc-2.17.so)
==37156== by 0x4E64611: __assert_fail (in /usr/lib64/libc-2.17.so)
==37156== by 0x40073C: sqlite3MemFree (in /home/jipeng/vc6_practice/SQLite/a.out)
==37156== by 0x4008A8: main (in /home/jipeng/vc6_practice/SQLite/a.out)
==37156==
==37156== HEAP SUMMARY:
==37156== in use at exit: 1,032 bytes in 1 blocks
==37156== total heap usage: 3 allocs, 2 frees, 1,197 bytes allocated
==37156==
==37156== LEAK SUMMARY:
==37156== definitely lost: 0 bytes in 0 blocks
==37156== indirectly lost: 0 bytes in 0 blocks
==37156== possibly lost: 0 bytes in 0 blocks
==37156== still reachable: 1,032 bytes in 1 blocks
==37156== of which reachable via heuristic:
==37156== length64 : 1,032 bytes in 1 blocks
==37156== suppressed: 0 bytes in 0 blocks
==37156== Rerun with --leak-check=full to see details of leaked memory
==37156==
==37156== For counts of detected and suppressed errors, rerun with: -v
==37156== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Aborted (core dumped)
从上面可以看到分配了供分配了1032字节,其中8字节用于头部,并且内存没有释放,所以发生了内存泄露。
释放函数
mem1 test
分配内存...
分配内存的大小为:1024
调整内存...
调整后的内存大小为:2048
==37210==
==37210== HEAP SUMMARY:
==37210== in use at exit: 2,056 bytes in 1 blocks
==37210== total heap usage: 2 allocs, 1 frees, 3,088 bytes allocated
==37210==
==37210== LEAK SUMMARY:
==37210== definitely lost: 2,056 bytes in 1 blocks
==37210== indirectly lost: 0 bytes in 0 blocks
==37210== possibly lost: 0 bytes in 0 blocks
==37210== still reachable: 0 bytes in 0 blocks
==37210== suppressed: 0 bytes in 0 blocks
==37210== Rerun with --leak-check=full to see details of leaked memory
==37210==
==37210== For counts of detected and suppressed errors, rerun with: -v
==37210== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
调整为2048,供分配了2056字节,发生了内存泄露。