编程接口指南

库级别动态内存

库级别动态内存分配为动态内存分配提供了一个易于使用的接口。

动态内存分配

最常用的接口包括:

其他动态内存分配接口包括 memalign(3C)valloc(3C)realloc(3C)

动态内存调试

Sun WorkShop 工具包有助于查找和消除在使用动态内存时出现的错误。Sun WorkShop 的运行时检查 (Run Time Checking, RTC) 工具使用本节中介绍的函数来查找使用动态内存时的错误。

RTC 不需要使用 -g 对程序进行编译以查找所有错误。不过,有时需要符号 (-g) 信息,以保证某些错误(尤其是从未初始化内存中读取的错误)的正确性。因此,如果没有可用的符号信息,则某些错误会受到抑制。这些错误包括 rui(针对 a.out)和 rui + aib + air(针对共享库)。可以使用 suppressunsuppress 来更改此行为。

check -access

-access 选项可用于启动访问检查。 RTC 将报告以下错误:

baf

错误释放

duf

重复释放

maf

未对齐的释放

mar

未对齐的读取

maw

未对齐的写入

oom

内存不足

rua

从未分配的内存读取

rui

从未初始化的内存读取

rwo

写入只读内存

wua

写入未分配的内存

缺省行为是在检测到每个访问错误之后停止进程。可以使用 rtc_auto_continue dbxenv 变量更改此行为。如果设置为 on,则 RTC 会将访问错误记录到文件中。文件名由 rtc_error_log_file_name dbxenv 变量的值确定。缺省情况下,仅在每个唯一的访问错误首次发生时报告该错误。可使用 rtc_auto_suppress dbxenv 变量更改此行为。此变量的缺省设置为 on

check -leaks [-frames n] [-match m]

-leaks 选项可用于启动泄漏检查。 RTC 将报告以下错误:

aib

可能的内存泄漏-仅有的指针指向块的中间位置

air

可能的内存泄漏-指向块的指针仅存在于寄存器中

mel

内存泄漏-没有指向块的指针

启动泄漏检查之后,在程序退出时会获取自动生成的泄漏报告。此时会报告包括潜在泄漏在内的所有泄漏。缺省情况下,将生成非详细报告。此缺省行为由 dbxenv rtc_mel_at_exit 控制。不过,可以随时要求提供泄漏报告。

报告泄漏时,-frames n 最多可显示 n 个不同的栈帧。-match m 变量用于合并泄漏。如果进行分配时两个或多个泄漏的调用栈与 m 帧匹配,则会在单个合并的泄漏报告中报告这些泄漏。n 的缺省值是 8 或 m 值之间的较大者。n 的最大值为 16。m 的缺省值为 2。

check -memuse [-frames n] [-match m]

-memuse 选项可用于启动内存使用 (memuse) 检查。如果使用 check -memuse,则表示同时启用了 check -leaks。除程序退出时获取泄漏报告之外,您还会获得一个列出使用中的块 (biu) 的报告。缺省情况下,将生成有关使用中的块的非详细报告。此缺省行为由 dbxenv rtc_biu_at_exit 控制。在程序执行过程中,可随时查看程序中的内存所分配到的位置。

-frames n-match m 变量的作用如以下部分所述。

check -all [-frames n] [-match m]

check -access; check -memuse [-frames n] [-match m] 等效。rtc_biu_at_exit dbxenv 变量的值不会随 check -all 进行更改。因此,缺省情况下,退出时不会生成任何内存使用报告。

check [funcs] [files] [loadobjects]

funcs files loadobjects 中的 check -all; suppress all; unsuppress all 等效。使用此选项可以将 RTC 重点用于所需的位置。

其他内存控制接口

本节介绍其他内存控制接口。

使用 sysconf

sysconf(3C) 可用于返回与系统相关的内存页的大小。为便于移植,应用程序不应嵌入用于指定页面大小的任何常量。请注意,即使在相同指令集的执行中,变化的页面大小也很常见。

使用 mprotect

mprotect(2) 可用于为指定地址范围内的所有页面提供指定的保护。保护不能超出底层对象所允许的权限。

使用 brksbrk

中断点 (break) 是进程映像中栈外部的最大的有效数据地址。程序开始执行时,execve(2) 通常会将中断点 (break) 值设置为程序及其数据存储所定义的最大地址。

使用 brk(2) 可将中断点 (break) 设置为更大的地址。您还可以使用 sbrk(2) 向进程的数据段中添加一个存储增量。通过调用 getrlimit(2) 可以获取数据段的最大可能大小。

caddr_t

 brk(caddr_t addr);



 caddr_t

 sbrk(intptr_t incr); 

brk 可用于将调用方未使用的最低数据段位置标识为 addr。此位置会向上舍入为系统页面大小的下一个倍数。

备用接口 sbrk 可用于向调用方数据空间中添加 incr 个字节,并返回指向新数据区域开头的指针。