核心基础为每次调用 CFSTR() 创建内存泄漏

Core Foundation creates a memory leak for every call to CFSTR()

本文关键字:创建 内存 泄漏 CFSTR 调用 核心      更新时间:2023-10-16

我通常使用 CFSTR() 宏从标准 c 字符串创建 CFString 对象,直到经过多次测试和更好地检查文档,我意识到每次调用此函数都会自动创建内存泄漏,直到程序终止。即使在应用程序关闭后,可视检漏仪仍会报告内存未释放。对 CFRetain、CFRelease 的任何调用都不会影响内存。由于我进行了大量调用,我想知道我是否应该使用 CFStringCreateWithCString,与 CFSTR 不同,内存在调用 CFRelease 后完全释放(正如内存泄漏检测工具报告的那样)。

谢谢

更新(回复评论):我在Windows上,我直接从我的c ++应用程序使用官方的CoreFoundation库。为了识别内存泄漏,我使用OpenCfLite,因为源代码是相同的,但允许我也包括Visual Leak Detector标头,或者,或者,只使用内置的Visual Studio泄漏检测器。当我关闭应用程序时,我会得到一个完整的报告,我可以清楚地看到内存地址及其内容。我可以从报告中看到,传递给 CFSTR(=__CFStringMakeConstantString) 的相同字符串仍然位于内存地址。这似乎不是错误或我做错了什么,而只是正常行为,因为正如Apple所说:"从CFSTR返回的值不会由CFString发布,并且保证在程序终止之前它们有效。

示例调用:CFSTR("此字符串已从__CFStringMakeConstantString函数创建")

---------------这是来自内置检漏仪Microsoft转储:-------------------

检测到内存泄漏!

倾倒对象 ->

C:\projects\cftest\cftest\cfbase.c(277) : {61} 0x00A01648的正常块,长度为 96 字节。

数据: <<strong>GThis st> 00 00 00 00 8C 07 00 00 47 54 68 69 73 20 73 74

对象转储完成。

---------------这是来自VLD工具的转储:---------------

---------- 块 1 在 0x04AD2FE8:4096 字节----------

调用堆栈:

0x77D89950 (File and line number not available): ntdll.dll!RtlQueryEnvironmentVariable + 0x241 bytes
0x77D8D8C9 (File and line number not available): ntdll.dll!LdrResSearchResource + 0xB4D bytes
0x77D8D78C (File and line number not available): ntdll.dll!LdrResSearchResource + 0xA10 bytes
0x77D8C4D5 (File and line number not available): ntdll.dll!LdrLoadDll + 0x7B bytes
0x772A2288 (File and line number not available): KERNELBASE.dll!LoadLibraryExW + 0x1F1 bytes
0x6FA4DF32 (File and line number not available): clr.dll!GetCLRFunction + 0x895F bytes
0x6FA4DFAD (File and line number not available): clr.dll!GetCLRFunction + 0x89DA bytes
0x6FC4ECF0 (File and line number not available): clr.dll!CorLaunchApplication + 0x17DB0 bytes
0x6F9F421B (File and line number not available): clr.dll!StrongNameSignatureVerification + 0x524C bytes
0x6F9F42E2 (File and line number not available): clr.dll!StrongNameSignatureVerification + 0x5313 bytes
0x6F9F3FE4 (File and line number not available): clr.dll!StrongNameSignatureVerification + 0x5015 bytes
0x6F9AD323 (File and line number not available): clr.dll!LogHelp_NoGuiOnAssert + 0x17457 bytes
0x6FA57D55 (File and line number not available): clr.dll!GetCLRFunction + 0x12782 bytes
0x6F9C52D5 (File and line number not available): clr.dll!LogHelp_TerminateOnAssert + 0x16F1D bytes
0x023D0882 (File and line number not available): (Module name unavailable)!(Function name unavailable)
0x00370AF3 (File and line number not available): (Module name unavailable)!(Function name unavailable)
0x6CC8CEA3 (File and line number not available): System.Windows.Forms.ni.dll!(Function name unavailable)
0x6C3A4D34 (File and line number not available): System.Windows.Forms.ni.dll!(Function name unavailable)
0x6C397BBB (File and line number not available): System.Windows.Forms.ni.dll!(Function name unavailable)
0x6C3979B8 (File and line number not available): System.Windows.Forms.ni.dll!(Function name unavailable)
0x6C3A3B37 (File and line number not available): System.Windows.Forms.ni.dll!(Function name unavailable)
0x6C399828 (File and line number not available): System.Windows.Forms.ni.dll!(Function name unavailable)
0x6C3A285A (File and line number not available): System.Windows.Forms.ni.dll!(Function name unavailable)
0x6C3A3A60 (File and line number not available): System.Windows.Forms.ni.dll!(Function name unavailable)
0x6C3A26D9 (File and line number not available): System.Windows.Forms.ni.dll!(Function name unavailable)
0x6C399513 (File and line number not available): System.Windows.Forms.ni.dll!(Function name unavailable)
0x6C399491 (File and line number not available): System.Windows.Forms.ni.dll!(Function name unavailable)
0x6C8F9B34 (File and line number not available): System.Windows.Forms.ni.dll!(Function name unavailable)
0x023D0E7B (File and line number not available): (Module name unavailable)!(Function name unavailable)
0x767262FA (File and line number not available): USER32.dll!gapfnScSendMessage + 0x332 bytes
0x76726D3A (File and line number not available): USER32.dll!GetThreadDesktop + 0xD7 bytes
0x76726DE8 (File and line number not available): USER32.dll!GetThreadDesktop + 0x185 bytes
.

.......GThis.st

72 69 6E 67 20 68 61 73 20 62 65 65 6E 20 63 72 环.has .been.cr

65

61 74 65 64 20 66 72 6F 6D 20 5F 5F 43 46 53 eated.fr om.__CFS

74 72 69 6E 67 4D 61 6B 65 43 6F 6E 73 74 61 6E tringMak eConstan

74

53 74 72 69 6E 67 20 66 75 6E 63 74 69 6F 6E tString. 函数

00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 .......

现在,我可以通过用 CFStringCreateWithCString 替换对 CFSTR 的任何调用来轻松避免上述所有问题,我确信没有内存泄漏(至少只要我记得调用 CFRelease),但我想知道为什么许多代码示例显示大量使用 CFSTR,如果每次调用此函数都将字符串存储在内存中,只有在程序终止时才能释放。

谢谢

我想你的问题也在这里得到了回答。如果要创建大量唯一字符串,则应使用 CFStringCreateWithCStringCFRelease 。另一方面,如果唯一字符串的数量很少(例如 100 个左右),则使用 CFSTR 没有问题。