我通常使用CFSTR()宏从标准c字符串创建CFString对象,直到经过多次测试并更好地检查文档后,我意识到每次调用此函数都会自动创建一个内存泄漏,直到程序终止。即使在应用程序关闭后,可视化泄漏检测器仍会将内存报告为未释放。 任何对CFRetain的调用,CFRelease都不会影响内存。 由于我进行了大量调用,我想知道是否应该使用CFStringCreateWithCString,与CFSTR不同,在调用CFRelease之后内存完全释放(也可以从内存泄漏检测工具中报告)。
由于
更新(回复评论): 我在Windows上,我直接从我的c ++应用程序使用官方CoreFoundation库。为了识别内存泄漏,我使用OpenCfLite,因为源代码是相同的,但允许我也包括Visual Leak Detector标头,或者只使用内置的Visual Studio泄漏检测器。当我关闭应用程序时,我得到一份完整的报告,我可以清楚地看到内存地址及其内容。我可以从报告中看到传递给CFSTR(= __ CFStringMakeConstantString)的相同字符串仍然位于内存地址。 这似乎不是一个错误或我做错的事情,而只是正常的行为,因为Apple声明:“从CFSTR返回的值不会被CFString释放,并且在程序终止之前它们保证有效。” / p>
示例电话: CFSTR(“此字符串已从__CFStringMakeConstantString函数”创建)
---------------这是来自Microsoft内置泄漏检测器的转储:---------------- --- 的
检测到内存泄漏!
转储对象 - >
c:\ projects \ cftest \ cftest \ cfbase.c(277):{61}正常块位于0x00A01648,96字节长。
数据:< 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 ring.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 00 ........ ........现在,我可以通过用CFStringCreateWithCString替换对CFSTR的任何调用来轻松避免所有上述问题,其中我确定没有内存泄漏(至少只要我记得调用CFRelease),但我想要知道为什么许多代码示例显示大量使用CFSTR如果每次调用此函数都将字符串存储在内存中,只有在程序终止时才可以释放。
由于
答案 0 :(得分:1)
我认为你的问题也已回答here。
如果要创建大量唯一字符串,则应使用CFStringCreateWithCString
和CFRelease
。另一方面,如果唯一字符串的数量很小(比如100左右),使用CFSTR
就没有问题。