gpt4 book ai didi

c - CFSTR() 是否分配内存?

转载 作者:太空狗 更新时间:2023-10-29 16:12:17 30 4
gpt4 key购买 nike

我理解 CFSTR() documentation表明它分配内存。它可以在失败时返回 NULL,并且无论调用 CFRelease() 还是删除引用,结果在程序终止之前都是可用的。它包装了静态字符串,但肯定它必须分配一个 CFString 类结构来这样做。因此,它不适合在长时间运行的程序中使用。

然而,在对此进行了一些反对之后,我尝试了以下测试程序。我没有看到 top 中的内存占用量增加。 valgrind 报告的泄漏不随循环大小而变化。是否进行了重复数据删除?

#include <CoreFoundation/CFString.h>
#include <stdio.h>

int main(void) {
int count = 0;
int chars = 0;
for (int i = 0; i < 100000000; i++) {
CFStringRef str = CFSTR("Goodbye.");
if (str) {
count++;
chars += CFStringGetLength(str);
// Drop reference!
}
}
printf("%d strings, %d chars\n", count, chars);
CFStringRef str = CFSTR("Hello, World.");
CFShowStr(str);
}

另一个提问者 reported CFSTR() 确实在 Windows 上泄漏。其他人说它就像 Objective C 的 @"String" 文字语法。 CFString 引用提到在 gcc 3.3 上需要 -fconstant-cfstrings。那么宏是否使用神奇的编译器扩展在构建时创建这些?

在我的 MacOS X 10.8.5 机器上,CoreFoundation/CFString.h 将 CFSTR 定义为 __builtin___CFStringMakeConstantString except 在 Windows 或 Linux 上,它使用非内置版本。

所以答案似乎很可能是“它不在 MacOS X 或 iOS 上分配”。

我不知道如何验证它们实际上作为 CFStringRefs 在可执行文件中,但是 otool -tV 说:

leaq    0x1c8(%rip), %rax ## Objc cfstring ref: @"Goodbye."

指令指针相对寻址是某种确认,leaq 意味着它没有调用任何可以分配的东西。

最佳答案

如您所见,在 Apple 平台上,CFSTR 使用内置编译器在编译时生成字符串。它作为完全构造的可用对象嵌入到可执行文件中;该程序不会在运行时为 CFSTR 执行任何分配。编译器将重复的字符串对象合并到一个翻译单元中。我不确定链接器是否合并了目标文件中的重复项。

在其他平台上,Apple 不控制编译器,因此它不能使用内置的编译器将构造的对象嵌入到可执行文件中。相反,在运行时,它调用私有(private)库函数 __CFStringMakeConstantString。您可以在 CFString.c 中找到该函数的源代码。 .它保留一个将参数(作为 C 字符串)映射到 CFString 的哈希表。这就是“重复数据删除”。它通常不会从表中删除条目。因此,传递给 CFSTR 的每个唯一 C 字符串都将分配一些内存,该内存会一直存在到程序存在为止。可以通过使用相同字符串参数调用 CFSTR 来访问内存,因此将其称为“泄漏”是有问题的。

关于c - CFSTR() 是否分配内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25752703/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com