首页 > 解决方案 > 取malloc()、realloc()和free()的地址是否可移植?

问题描述

malloc()根据标准,获取、realloc()和的地址是否安全free()

例如,

#include <stdlib.h>
void * (*my_malloc)(size_t) = &malloc;

推论,在符合标准的 C 中,实现是否有可能使用//malloc的宏reallocfree

标签: cstandards

解决方案


是的,这是安全的。标准库允许为其任何函数定义类似函数的宏,但它们也必须作为函数可用。

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++);对于函数或宏来说都是安全的。


推荐阅读