我正在编写一个库,并希望使它绝对与资源无关,这也意味着库应该与用户提供的内存分配功能一起使用.库允许用户也设置自己的错误处理函数,这些函数使用错误消息作为参数调用,如下所示:
typedef void (*error_handler)(const char* msg);
char buf[BUF_SIZE]; snprintf(buf,BUF_SIZE,"Oops found at file '%s' line %d",__FILE__,__LINE__);
但是我可以确定snprintf不会为malloc的内部使用分配更多的内存,显然会绕过用户提供的分配例程吗?我的Linux系统中的手册页对此保持沉默.
解决方法
与任何库例程一样,sprintf和snprintf可能会也可能不会为内部使用分配内存.
它们不会为结果字符串分配内存.必须由调用者以某种方式分配该内存,并将其地址作为第一个参数传递.如果分配的内存不够大,那么sprintf将具有未定义的行为(因为没有办法告诉它有多少可用空间),并且snprintf将截断结果(假设size参数是准确的).
如果sprintf或snprintf的实现分配内存并且没有安排它被释放,那将是内存泄漏.这样的泄漏实际上不会违反语言标准(对资源分配没什么好说的),但它会被认为是该实现中的一个错误.
特别是,如果您自己的代码使用自己的内存分配器而不是malloc,那么您调用的任何库函数都可以在内部调用malloc,除非您使用某些特定于系统的功能来调用malloc(即使在标准库中)调用您的分配器代替.例如,fopen()特别有可能为缓冲区分配内存.
如果您通过调用自己的分配器来替换标准库对malloc的调用,则需要确保还替换对realloc,calloc和free以及可能的一个或多个特定于系统的例程的任何调用.例如,在程序完成时运行的清理代码将关闭打开的文件,这可能涉及对free的调用.