STL函数:static void (* set_malloc_handler(void (*f)()))()分析

本文深入解析了函数指针的概念及应用,包括如何声明函数指针、如何使用函数指针作为形参和返回值,并通过具体例子说明了这些概念的实际运用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题由来

在阅读《STL源码剖析》的时候遇到一个函数

static void (* set_malloc_handler(void (*f)()))()
{
    void (* old)() = __malloc_alloc_oom_handler;
    __malloc_alloc_oom_handler = f;
    return(old);
}

要弄明白这个问题,首先得知道函数指针。

函数指针

reference:《C++ primer》第五版

函数指针指向一个函数,它所指向的类型由其所指向的函数的返回类型和形参类型共同决定。比如下面这个函数

bool lengthCompare(const string &, cosnt string &);

这个函数类型是bool (const string &, const string &).现在我们声明一个函数指针,用指针替换函数名

bool (*pf)(const string &, cosnt string &);

观察这个声明:pf前面的*表示pf是一个指针,右侧形参列表表示pf是指向一个函数,左侧函数的返回值是bool类型。

使用函数指针:先让函数指针指向一个函数,然后这个指针就和函数名一样使用

pf = lengthCompare;
bool b1 = pf("hello", "goodbye");

函数指针作为形参(重要)

以下函数的第3个参数为一个函数指针

void useBigger(const string &s1, const string &s2, bool (*pf)(const string &, const string &));

当使用的时候,我们可以直接把函数作为实参传入,它便自动转为指针

useBigger(s1, s2, lengthCompare);

函数指针作为返回值(重要)

using F = int(int*, int);       //F为函数类型
using PF = int(*)(int*, int);   //PF为函数指针类型
PF fl(int);     //f1和f2都是返回函数指针类型
F* f2(int);

我们也可这样声明f1:

int (*f1(int)) (int*, int);

由内向外读:f1有形参列表,是一个函数;前面有一个*,所以f1返回一个指针;进一步观察,指针类型本身也包含形参列表,因此指针指向函数,该函数(就是指针指向的函数)的返回类型为int.

分析static void (* set_malloc_handler(void (*f)()))()

static void (* set_malloc_handler(void (*f)()))()
{
    void (* old)() = __malloc_alloc_oom_handler;
    __malloc_alloc_oom_handler = f;
    return(old);
}

从里往外读:set_malloc_handlers有形参列表,是一个函数;函数参数为void(f)(),很显然,这个参数是一个函数指针,参数为空,返回类型也为空;函数名前面有一个,所以返回一个指针;进一步观察这个指针类型也有参数列表,因此该指针指向一个函数,这个函数的参数为空,返回类型为void;因此:函数set_malloc_handler的参数为void()()类型,返回值也为void()()类型。

typedef void(*MALLOCALLOC)(); //将void (*)() 重命名成MALLOCALLOC template<int inst> class _MallocAllocTemplate { private: static void* _OomMalloc(size_t); //malloc失败的时候调用的函数 static MALLOCALLOC _MallocAllocOomHandler; //函数指针,内存不足的时候的处理机制 public: static void* _Allocate(size_t n) //分配空间n个字节的空间 { void *result=0; result = malloc(n); if (0 == result) //若果malloc失败,则就调OOM_malloc _OomMalloc(n); return result; } static void _DeAllocate(void *p) //释放这块空间 { free(p); } static MALLOCALLOC _SetMallocHandler(MALLOCALLOC f) //这是一个函数,参数是一个函数指针,返回值也是一个函数指针 { MALLOCALLOC old = _MallocAllocOomHandler; _MallocAllocOomHandler = f; //将内存分配失败的句柄设置为f(让它指向一个内存失败了,让系统去释放其他地方空间的函数) return old; } }; template<int inst> void(* _MallocAllocTemplate<inst>::_MallocAllocOomHandler)()=0; //默认不设置内存不足处理机制 template<int inst> void* _MallocAllocTemplate<inst>::_OomMalloc(size_t n) { MALLOCALLOC _MyMallocHandler; //定义一个函数指针 void *result; while (1) { _MyMallocHandler = _MallocAllocOomHandler; if (0 == _MyMallocHandler) //没有设置内存不足处理机制 throw std::bad_alloc(); //则抛出异常 (*_MyMallocHandler)(); //调用内存不足处理的函数,申请释放其他地方的内存 if (result = malloc(n)) //重新申请内存 break; } return result; //申请成功时,则返回这块内存的地址 } typedef _MallocAllocTemplate<0> malloc_alloc;请你仔细分析上述代码的逻辑,并说明每一行代码的作用,此外对 (*_MyMallocHandler)(); //调用内存不足处理的函数,申请释放其他地方的内存这一行代码我不明白,它是怎么申请释放内存的?
03-22
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值