- C++11版本开始支持智能指针的原理其实就是引用计数,C并不原生支持,但可以通过一些方法模拟出来,下面是参考 libre 的实现,可以使用 Valgrind 调试内存的使用状态,不废话,用代码解释代码:
#include <stdio.h>
#include <ctype.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
typedef void (mem_destroy_h)(void *data);
/** Defines a reference-counting memory object */
struct mem {
uint32_t nrefs; /**< Number of references */
mem_destroy_h *dh; /**< Destroy handler */
};
/**
* Allocate a new reference-counted memory object
*
* @param size Size of memory object
* @param dh Optional destructor, called when destroyed
*
* @return Pointer to allocated object
*/
void *mem_alloc(size_t size, mem_destroy_h *dh)
{
struct mem *m;
m = malloc(sizeof(*m) + size);
if (!m)
return NULL;
m->nrefs = 1;
m->dh = dh;
return (void *)(m + 1);
}
/**
* Reference a reference-counted memory object
*
* @param data Memory object
*
* @return Memory object (same as data)
*/
void *mem_ref(void *data)
{
struct mem *m;
if (!data)
return NULL;
m = ((struct mem *)data) - 1;
++m->nrefs;
return data;
}
/**
* Dereference a reference-counted memory object. When the reference count
* is zero, the destroy handler will be called (if present) and the memory
* will be freed
*
* @param data Memory object
*
* @return Always NULL
*/
void *mem_deref(void *data)
{
struct mem *m;
if (!data)
return NULL;
m = ((struct mem *)data) - 1;
if (--m->nrefs > 0)
return NULL;
if (m->dh)
m->dh(data);
/* NOTE: check if the destructor called mem_ref() */
if (m->nrefs > 0)
return NULL;
free(m);
return NULL;
}
int main(int argc, const char * argv[])
{
void * data_foo = mem_alloc(512, NULL);
data_foo = mem_deref(data_foo);
return 0;
}
参考文档:
- https://github.com/creytiv/re/