“Tcl_Free()”与“Free()”有何不同?
这些描述似乎几乎完全相同。这两者之间有没有需要注意的细微差别?为什么有人会用一个而不是另一个?对于“Tcl_Free()”与“Free()”有何不同?,c,tcl,C,Tcl,这些描述似乎几乎完全相同。这两者之间有没有需要注意的细微差别?为什么有人会用一个而不是另一个?对于Tcl_Alloc()和malloc()也可能会提出这个问题,因为Tcl支持使用一个工具链在Windows上构建,并加载使用不同工具链构建的DLL。该场景的一个关键特性是,不同的工具链有自己的C库实现是很常见的,这意味着malloc()的不同实现。您必须将malloc()和free()匹配到同一个库,否则通过提供Tcl\u Alloc和Tcl\u free(通常是非常薄的包装)会出现一些真正奇怪的故
Tcl_Alloc()
和malloc()
也可能会提出这个问题,因为Tcl支持使用一个工具链在Windows上构建,并加载使用不同工具链构建的DLL。该场景的一个关键特性是,不同的工具链有自己的C库实现是很常见的,这意味着malloc()
的不同实现。您必须将malloc()
和free()
匹配到同一个库,否则通过提供Tcl\u Alloc
和Tcl\u free
(通常是非常薄的包装)会出现一些真正奇怪的故障(崩溃、内存泄漏等)它使用户代码能够正确地匹配分配和发布。之所以使用它们,是因为Tcl支持使用一个工具链在Windows上构建,并加载使用不同工具链构建的DLL。该场景的一个关键特性是,不同的工具链有自己的C库实现是很常见的,这意味着malloc()
的不同实现。您必须将malloc()
和free()
匹配到同一个库,否则通过提供Tcl\u Alloc
和Tcl\u free
(通常是非常薄的包装)会出现一些真正奇怪的故障(崩溃、内存泄漏等)这使得用户代码能够正确匹配分配和发布。这通常是最明显的原因:
通常,使用您自己版本的内存分配函数的最好理由是有一个单一的定义,允许您为不同的分配器更改内存分配器。(调试、扩展或使用安全选项实现等)
假设您有以下实现:
void *my_malloc(size_t siz)
{
return malloc(siz);
}
void my_free(void *ptr)
{
free(ptr);
}
定义于分配器\u malloc.c
对于特殊客户X,您已经获得了新ACME分配器的许可证。对于该客户,您可以将可执行文件链接到文件allocator\u ACME.c
,该文件包含:
void *my_malloc(size_t siz)
{
return ACME_malloc(siz);
}
void free(void *ptr)
{
ACME_free(ptr);
}
然后,只需将可执行文件与一个或另一个文件链接,就可以生成标准库malloc()
的依赖项,或者必须提供ACME\u malloc()
函数的实现。这样,只需更改多个对象文件中的一个文件,即可将整个依赖项集(假设您在源文件中同时定义了my_malloc()
和my_free()
)更改为多个不同的实现之一
缺点是您有一个级别的函数调用,因此在某些情况下,必须使用一个更可靠的解决方案
假设您购买了一个自动垃圾回收器,因此您不需要返回分配给malloc的内存,就像一些魔术一样,库将检测到您没有更多地使用它,并且它会自动垃圾回收它:
void *my_malloc(size_t siz)
{
return GC_malloc(siz);
}
void my_free(void *ptr)
{
/* empty */
}
这通常是最明显的理由: 通常,使用您自己版本的内存分配函数的最好理由是有一个单一的定义,允许您为不同的分配器更改内存分配器。(调试、扩展或使用安全选项实现等) 假设您有以下实现:
void *my_malloc(size_t siz)
{
return malloc(siz);
}
void my_free(void *ptr)
{
free(ptr);
}
定义于分配器\u malloc.c
对于特殊客户X,您已经获得了新ACME分配器的许可证。对于该客户,您可以将可执行文件链接到文件allocator\u ACME.c
,该文件包含:
void *my_malloc(size_t siz)
{
return ACME_malloc(siz);
}
void free(void *ptr)
{
ACME_free(ptr);
}
然后,只需将可执行文件与一个或另一个文件链接,就可以生成标准库malloc()
的依赖项,或者必须提供ACME\u malloc()
函数的实现。这样,只需更改多个对象文件中的一个文件,即可将整个依赖项集(假设您在源文件中同时定义了my_malloc()
和my_free()
)更改为多个不同的实现之一
缺点是您有一个级别的函数调用,因此在某些情况下,必须使用一个更可靠的解决方案
假设您购买了一个自动垃圾回收器,因此您不需要返回分配给malloc的内存,就像一些魔术一样,库将检测到您没有更多地使用它,并且它会自动垃圾回收它:
void *my_malloc(size_t siz)
{
return GC_malloc(siz);
}
void my_free(void *ptr)
{
/* empty */
}
从手册页:这些过程为内存分配提供了一个独立于平台和编译器的接口。因此,它也可能被移植到不支持malloc()
接口而不更改源代码的平台。实际上,在大多数平台上,它可能只调用malloc()
。或者,它还可以额外收集内存统计信息:当Tcl和所有调用Tcl的模块在定义了Tcl_MEM_DEBUG的情况下编译时,这些宏被重新定义为这些过程的特殊调试版本。从主页上看:这些过程为内存分配提供了独立于平台和编译器的接口。因此,它也可能被移植到不支持malloc()
接口而不更改源代码的平台。实际上,在大多数平台上,它可能只调用malloc()
。或者,它还可以另外收集内存统计信息:当编译Tcl和所有调用Tcl的模块时,定义了Tcl_MEM_DEBUG,但是,这些宏被重新定义为这些过程的特殊调试版本。