0

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

谢谢

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

示例调用: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 工具的转储:----------------

---------- 0x04AD2FE8 处的块 1: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 吃过。来自 .__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 的大量使用,只有在程序终止时才可以释放该字符串。

谢谢

4

1 回答 1

1

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

于 2013-02-07T06:40:15.480 回答