c - 取malloc()、realloc()和free()的地址是否可移植?
问题描述
malloc()
根据标准,获取、realloc()
和的地址是否安全free()
?
例如,
#include <stdlib.h>
void * (*my_malloc)(size_t) = &malloc;
推论,在符合标准的 C 中,实现是否有可能使用//malloc
的宏realloc
?free
解决方案
是的,这是安全的。标准库允许为其任何函数定义类似函数的宏,但它们也必须作为函数可用。
C17 7.1.4 (1)
头文件中声明的任何函数都可以额外实现为头文件中定义的类函数宏,因此如果在包含头文件时显式声明库函数,则可以使用下面显示的技术之一来确保声明不受这样一个宏的影响。函数的任何宏定义都可以通过将函数的名称括在括号中来在本地抑制,因为该名称后面没有表示宏函数名称扩展的左括号。出于同样的语法原因,即使库函数也被定义为宏,也允许获取库函数的地址。[189]
[189] 这意味着实现应为每个库函数提供一个实际函数,即使它还为该函数提供了一个宏。
所以简而言之,图书馆的标题可以有类似的东西
void *malloc(size_t);
#define malloc(s) __fancy_internal_malloc((s) + 47 | 0x14 * 3)
所以你可以做任何
void *p = malloc(10); // invokes the macro if there is one
void *q = (malloc)(10); // definitely calls the function, not the macro
void *(*allocator)(size_t) = &malloc; // takes address of the function
#undef malloc
void *r = malloc(10); // definitely the function
当然,函数和宏都必须提供标准所承诺的任何行为(尽管正如 Eric Postpischil 评论的那样,只要每个都符合,它们的行为就不必相同)。特别是,使用宏进行分配和使用函数释放必须是安全的,反之亦然。此外,这样的宏必须只对每个参数进行一次评估,因此p = malloc(s++);
对于函数或宏来说都是安全的。
推荐阅读
- android - 未解决的参考:绑定 - Kotlin Android
- ios - NavigationBar 和 TabBar 背景颜色始终为灰色
- firebase - 如何将我的标记从 Firestore 检索到 Google Map?
- c - 如何打印带有名称的数组
- python - 使用 python -m chatterbot --version 检查 chatter 的版本。这是错误
- api - Python 和请求中的 REST API 和 P12 证书的新功能
- swift - Swift 将框架多个异步请求响应合二为一
- informix - Informix SQL 11.5 将多个查询结果存储在一个文件中
- bash - 如何将 bash 脚本的输出写入包含标题的 CSV 文件的第二行?
- sql - 有条件地引用 Oracle APEX 中的复选框值