2011-01-01 20 views
5

私はこれまでの回答をすべて見てきましたが、見つからないようです。 (私はC++での経験がかなり限られています)ポインタを解放できるかどうかを確認する

私のライブラリでは、私は文字列を解放します。 (驚いたことに?)

ここで問題が発生します。私は、ヒープ上に割り当てられるかもしれないchar *を含む構造体を持っているか、そうでないかもしれません。それは有効なポインタですが、解放することはできません。

IE

char* s1 = "A String"; 
char* s2 = (char*)memcpy(malloc(9), s1, 9); 

free(s2); 
free(s1); 

が上のエラーが発生します "無料(S1);"s1は実際にはが解放される必要があるため、解放するにはが必要です(これはヒープ上にありません)。これをどのように「許容される」方法で処理できますか? (似たような話題で、 "それをクラッシュさせよう"という答えは妥当ではないように思われる)

構造体はライブラリだけで作成されているわけではないので、何かを使って文字列を正しくコピーすることを保証することはできないmemcpyのように。

これはWindowsライブラリであるため、ISO Cや標準C関数の使用については心配する必要はありません。

+0

ベストの答え(私見): 'struct'はもっぱら図書館で作成し_is_ことを保証するために、不透明なポインタを使用してください。 (Windowsを使用しているともっと助けてくれるでしょう) –

+0

最悪の場合は最悪になりますが、SEHを使用することもできます(後者は私に何か間違っているように感じさせるでしょう) – James

+0

これがWindowsライブラリであることを確認するには、引数をBSTRにします。次に、ユーザが適切に( 'SysAllocString'を使って)それを割り当てる必要があり、あなたは一致するデアロケータを使うことが保証されています。他の方法はちょうど...悪いです。もしあなたのユーザが別のコンパイラを持っていれば、 'malloc'を使っても' free() 'できません。 –

答えて

2

これはWindowsライブラリであるため、引数をBSTRにしてください。次に、ユーザに適切に割り当てることが必要です(SysAllocString)。a matching deallocatorを使用することが保証されています。

他の方法はちょっと...悪いです。あなたのユーザが別のコンパイラを持っている場合、mallocを使っても、free()の文字列は使用できません。

は[注:ジェームズの要求にコメントから変換され、これは本当にhis suggestionsの最後のちょうどWindows固有のケースである]

さらにノート:BSTRはUnicodeです。私はまあまあ、ANSI文字列を格納するためにBSTRアロケータを使用する方法を見て覚えているようだが、SysAllocStringByteLenがそうだが、BSTRにANSIデータを入れることは、BSTRに精通している人にとっては、

+0

申し訳ありませんが、ネイティブC++の.NETコードを扱う際には、(とSAFEARRAY)を使用する必要があるときに、bstrに関するいくつかの悪い経験があることを覚えているようです。 それはオフトピックですが、私はそれを試してみましょう。 – James

+0

@James:BSTRではなく難しさを引き起こしたCOMコードだと思われます。 BSTR関数は実際にはシンプルで、CやC++から簡単に使えます。私は、VC++が範囲外になると自動的にBSTRを解放するラッパークラスを提供すると思いますが、それは多くの機能を追加するものではありませんし、それが私の気になる動作を正確に知っていないので、 'SysAllocString'と' SysFreeString '直接。 –

6

C++では、これについて全く心配するべきではありません。 std::stringを使用し、メモリを自動的に管理します。 Don't manage memory manually.

手動でこれを行うとしたら、あなたはライブラリのユーザーを作る

  • により、リソースを自分で管理する必要がありますメモリ自分自身を管理し、またはあなたを伝えるために、ユーザが必要な
  • メモリを管理する方法、または
  • を使用して、メモリをどのように管理し、次にユーザーが準拠するかをユーザーに伝えます。
+1

これは、(1)Windows上のライブラリ(2)、(3)コメントに応じて明らかにプリコンパイルされていることを除いて、大きなアドバイスです。そして 'std :: string'は、Windows上でモジュールの境界を越えて渡すことは安全ではないと判断されます。 Win32 APIのパターンに従い、Windowsライブラリがメモリを処理するのに好ましい方法です。 –

+0

@Ben:Windowsプログラミング:私の特技ではない(面白い、私が推測する)。もちろんそうです。ライブラリーとそれに対するリンクの両方のビルドプロセスを制御できない場合、これはかなり問題になります。私は答えとして投稿した場合、あなたのBSTRソリューションをupvoteしたいと思います。それが最も合理的な解決策である、IMOです。 –

0

malloc char *s1と値"A String"を値として設定できます。その後、無料s1することができます。

+0

私は知っていますが、誰かが行く場合 struct-> val = "random"; 私は再び問題を解決します – James

0

これはコンパイル時に知られている種類のものです。あなたはコードを見て、何を解放し、何を解放するかを知っています。したがって、実行時にそれを延期する方法を考えないでください。この場合、あなたが方法を見つけられないことは別として、C++でやり方が間違っているからです。静的に行うことができるときは、静的に行います。

タイプシステムを使用してください。 RAIIを使用してください。

+0

問題は、__my__コンパイル時に、実際に私のライブラリを呼び出す人々のためにのみ知っているということです。ポインタは単なる数値です。 – James

+1

@ジェームスこれは約**所有権**です。質問する質問は、誰がポインタを所有しているかです。これは、関数のドキュメントで言うことです。いずれにしても、呼び出し元はポインタを解放するかどうかを確認しないでください。繰り返しますが、これはあなたが明確にする必要のある静的な情報です。 – wilhelmtell

0

すべての文字列をヒープに格納すると、それらをすべて解放する必要があることがわかります。文字列がグローバルメモリのように存在する場合は、ヒープバッファにコピーします。

+0

誰のヒープですか? Windowsでは、各ライブラリは互換性のない互換性のないmalloc/freeヒープを取得する傾向があります。 Win32 APIの関数 'HeapAlloc'と' HeapFree'はモジュールの境界を越えて機能しますが、CRTが提供するmallocと互換性がなく、いずれのモジュールでも使用できません。 –

+0

OPがヒープに格納された文字列をどのように割り当てたかに応じて、malloc()によって使用されるヒープ。 –

0

私は以前はスタックで割り当てられた文字列と、ヒープで割り当てられた文字列を使用していましたが、最終的に他の共通コードに渡されました。

私がその場合に行ったことは、2つのポインタを持つことです。 1つはNULLか、ヒープ割り当て文字列です。もう1つのポインタは、スタック割り当てまたは同じヒープ割り当てメモリを指します。あなたが自由()をするために行くとき、あなたは前のポインタだけをチェックします。

もちろん、公開されているAPIでは厄介なように見えます。私の場合、内部コードのみでした。

関連する問題