check -leaks [-frames n ] [-match m]
check -memuse [-frames n] [-match m]
check -all [-frames n] [-match m]
库级别动态内存分配为动态内存分配提供了一个易于使用的接口。
最常用的接口包括:
其他动态内存分配接口包括 memalign(3C)、valloc(3C) 和 realloc(3C)。
free 可用于将通过 malloc、calloc、realloc、memalign 或 valloc 获取的内存返回到系统内存。尝试释放不是由动态内存分配接口所保留的块是一个错误,可能会导致进程崩溃。
calloc 可用于返回一个指向初始化为零的内存块的指针。可以通过 watchmalloc 或 free 将 calloc 保留的内存返回到系统。内存会进行分配并对齐,以包含具有指定大小的指定元素数的数组。
realloc 可用于更改分配给进程的内存块的大小,使用 realloc 可增大或减小分配的内存块的大小。realloc 是缩减内存分配而不会导致问题的唯一方法。重新分配的块在内存中的位置可能会更改,但是在分配大小更改之前的内容将保持不变。
Sun WorkShop 工具包有助于查找和消除在使用动态内存时出现的错误。Sun WorkShop 的运行时检查 (Run Time Checking, RTC) 工具使用本节中介绍的函数来查找使用动态内存时的错误。
RTC 不需要使用 -g 对程序进行编译,即可查找所有错误。不过,有时需要符号 (-g) 信息,以保证某些错误(尤其是从未初始化内存中读取的错误)的正确性。因此,如果没有可用的符号信息,则某些错误会受到抑制。这些错误包括 rui(针对 a.out)和 rui + aib + air(针对共享库)。可以使用 suppress 和 unsuppress 来更改此行为。
-access 选项可用于启动访问检查。RTC 会报告以下错误:
可用项错误
可用项重复
可用项排列错误
读取排列错误
写入排列错误
内存不足
从未分配的内存读取
从未初始化的内存读取
写入到只读内存
写入到未分配的内存
缺省行为是在检测到每个访问错误之后停止进程。可以使用 rtc_auto_continue dbxenv 变量更改此行为。如果设置为 on,则 RTC 会将访问错误记录到一个文件中。此文件名由 rtc_error_log_file_name dbxenv 变量的值确定。缺省情况下,仅在每个唯一的访问错误首次发生时报告该错误。可使用 rtc_auto_suppress dbxenv 变量更改此行为。此变量的缺省设置为 on。
-leaks 选项可启用泄漏检查。RTC 会报告以下错误:
可能发生内存泄漏-唯一指针指向块中间位置
可能发生内存泄漏-指向块的指针仅存在于寄存器中
内存泄漏-无指向块的指针
启用泄漏检查后,在程序退出时会获取自动生成的泄漏报告。此时会报告包括潜在泄漏在内的所有泄漏。缺省情况下,将生成非详细报告。此缺省行为由 dbxenv rtc_mel_at_exit 控制。不过,可以随时要求提供泄漏报告。
报告泄漏时,-frames n 变量最多可显示 n 个不同的栈帧。-match m 变量用于合并泄漏。如果进行分配时两个或多个泄漏的调用栈与 m 个帧匹配,则会在单个合并的泄漏报告中报告这些泄漏。n 的缺省值为 8 或 m 值之间的较大者。n 的最大值为 16。m 的缺省值为 2。
-memuse 选项可启用内存使用 (memuse) 检查。使用 check -memuse 即表示使用 check -leaks。除程序退出时获取泄漏报告之外,您还会获得一个列出使用中的块 (biu) 的报告。缺省情况下,将生成有关使用中的块的非详细报告。此缺省行为由 dbxenv rtc_biu_at_exit 控制。在程序执行过程中,可随时查看程序中的内存所分配到的位置。
-frames n 和 -match m 变量的作用如下节所述。
与 check -access;check -memuse [-frames n] [-match m] 等效。rtc_biu_at_exitdbxenv 变量的值不会随 check -all 进行更改。因此,缺省情况下,退出时不会生成任何内存使用报告。
与 funcs files loadobjects 中的 check -all;suppress all;unsuppressall 等效。使用此选项可以将 RTC 重点用于所需的位置。
本节讨论其他内存控制接口。
sysconf(3C) 可用于返回与系统相关的内存页的大小。为便于移植,应用程序不应嵌入用于指定页面大小的任何常量。请注意,即使在相同指令集的执行中,变化的页面大小也很常见。
mprotect(2) 可用于为指定地址范围内的所有页面分配指定的保护。保护不能超出底层对象所允许的权限。
中断点 (break) 是进程映像中栈外部的最大的有效数据地址。程序开始执行时,execve(2) 通常会将中断点 (break) 值设置为程序及其数据存储所定义的最大地址。
使用 brk(2) 可将中断点 (break) 设置为更大的地址。您还可以使用 sbrk(2) 向进程的数据段中添加一个存储增量。通过调用 getrlimit(2) 可以获取数据段的最大可能大小。
caddr_t brk(caddr_t addr); caddr_t sbrk(intptr_t incr);