0

私は通常、CFSTR() マクロを使用して、標準の C 文字列から CFString オブジェクトを作成します。いくつかのテストとドキュメントの確認を行った後、この関数を呼び出すたびに、プログラムが終了するまで存続するメモリ リークが自動的に発生することに気付きました。ビジュアル リーク ディテクターは、アプリケーションを閉じた後でもメモリが解放されていないと報告します。CFRetain、CFRelease を呼び出しても、メモリにはまったく影響しません。私はたくさんの呼び出しを行うので、CFSTR とは異なり、CFRelease を呼び出した後にメモリが完全に解放される CFStringCreateWithCString を使用する必要があるかどうか疑問に思っていました (メモリ リーク検出ツールからも報告されています)。

ありがとう

更新 (コメントへの返信): 私は 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 バイト。

データ: < 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 食べる.from.__CFS

74 72 69 6E 67 4D 61 6B 65 43 6F 6E 73 74 61 6E トリングメイク 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 .........................

ここで、CFSTR への呼び出しを CFStringCreateWithCString に置き換えることで、上記の問題をすべて簡単に回避できます (少なくとも CFRelease を呼び出すことを覚えている限り) メモリ リークはありませんが、その理由を知りたいです。多くのコード サンプルは、この関数を呼び出すたびに文字列をメモリに格納し、プログラムが終了したときにのみ解放できる場合に、CFSTR が多用されていることを示しています。

ありがとう

4

1 に答える 1