`Tcl_Free()` 与 `free()` 有何不同?
How does `Tcl_Free()` differ from `free()`?
这些描述看起来几乎完全相同。两者之间有什么细微差别需要注意吗?为什么有人会使用一个而不是另一个? Tcl_Alloc()
和 malloc()
.
也可能会提出这个问题
使用它们是因为 Tcl 支持使用一个工具链在 Windows 上构建,并加载使用不同工具链构建的 DLL。该场景的一个关键特征是不同的工具链拥有自己的 C 库实现是相当普遍的,这意味着 malloc()
的不同实现。您 必须 将 malloc()
和 free()
匹配到同一个库,否则您会遇到一些非常奇怪的故障(崩溃、内存泄漏等)通过提供 Tcl_Alloc
和 Tcl_Free
(通常是非常薄的包装器)它使用户代码可以正确匹配分配和释放。
这通常是最明显的原因:
通常情况下,使用您自己版本的内存分配函数的最佳理解原因是拥有一个单一的定义,允许您为不同的分配器更改内存分配器。 (调试、扩展或使用安全选项实现等)
假设您有以下实现:
void *my_malloc(size_t siz)
{
return malloc(siz);
}
void my_free(void *ptr)
{
free(ptr);
}
定义于allocator_malloc.c
对于特殊客户 X,您已获得新 ACME 分配器的许可证。对于此客户,您 link 带有文件 allocator_ACME.c
的可执行文件包含:
void *my_malloc(size_t siz)
{
return ACME_malloc(siz);
}
void free(void *ptr)
{
ACME_free(ptr);
}
然后,只需 link 将您的可执行文件与一个或另一个文件相结合,即可生成标准库的依赖项 malloc()
,否则您将必须提供 [=16] 的实现=] 功能。这样,只需更改几个目标文件之一的存在,就会将整个依赖项集(假设您在源文件中对 my_malloc()
和 my_free()
都有定义)更改为几个不同的实现之一.
缺点是多了一层函数调用,所以在某些情况下必须使用更复杂的解决方案。
假设你买了一个自动垃圾收集器,所以你不需要return用malloc分配的内存,至于一些魔法,库会检测到你没有使用它,并且它会自动收集垃圾:
void *my_malloc(size_t siz)
{
return GC_malloc(siz);
}
void my_free(void *ptr)
{
/* empty */
}
这些描述看起来几乎完全相同。两者之间有什么细微差别需要注意吗?为什么有人会使用一个而不是另一个? Tcl_Alloc()
和 malloc()
.
使用它们是因为 Tcl 支持使用一个工具链在 Windows 上构建,并加载使用不同工具链构建的 DLL。该场景的一个关键特征是不同的工具链拥有自己的 C 库实现是相当普遍的,这意味着 malloc()
的不同实现。您 必须 将 malloc()
和 free()
匹配到同一个库,否则您会遇到一些非常奇怪的故障(崩溃、内存泄漏等)通过提供 Tcl_Alloc
和 Tcl_Free
(通常是非常薄的包装器)它使用户代码可以正确匹配分配和释放。
这通常是最明显的原因:
通常情况下,使用您自己版本的内存分配函数的最佳理解原因是拥有一个单一的定义,允许您为不同的分配器更改内存分配器。 (调试、扩展或使用安全选项实现等)
假设您有以下实现:
void *my_malloc(size_t siz)
{
return malloc(siz);
}
void my_free(void *ptr)
{
free(ptr);
}
定义于allocator_malloc.c
对于特殊客户 X,您已获得新 ACME 分配器的许可证。对于此客户,您 link 带有文件 allocator_ACME.c
的可执行文件包含:
void *my_malloc(size_t siz)
{
return ACME_malloc(siz);
}
void free(void *ptr)
{
ACME_free(ptr);
}
然后,只需 link 将您的可执行文件与一个或另一个文件相结合,即可生成标准库的依赖项 malloc()
,否则您将必须提供 [=16] 的实现=] 功能。这样,只需更改几个目标文件之一的存在,就会将整个依赖项集(假设您在源文件中对 my_malloc()
和 my_free()
都有定义)更改为几个不同的实现之一.
缺点是多了一层函数调用,所以在某些情况下必须使用更复杂的解决方案。
假设你买了一个自动垃圾收集器,所以你不需要return用malloc分配的内存,至于一些魔法,库会检测到你没有使用它,并且它会自动收集垃圾:
void *my_malloc(size_t siz)
{
return GC_malloc(siz);
}
void my_free(void *ptr)
{
/* empty */
}