4

アプリケーションの設計に関して1つ質問があります。擬似コードは次のとおりです。

char* buffer_to_be_filled = (char*) malloc(somesize);
fill_the_buffer(buffer_to_be_filled);
free(buffer_to_be_filled);

fill_the_buffer問題は、どれくらいのサイズが必要かわからないことです。

fill_the_buffer関数内の解決策を考えていました。必要に応じて、内部のスペースを再割り当てすることもできます。問題は、私が利用できるスペースの量を知る方法はありますか?

これは通常どのように解決されますか?バッファを割り当てる人もバッファを再割り当てする必要があると思いますよね?

注:fread関数を使用してバッファーを埋めているので、必要なスペースがわかりません。

4

4 に答える 4

3

渡されたのと同じポインターを返すことが保証されていないため、関数reallocは渡されたポインターを返すことreallocができません(新しいバッファーは大きすぎてインプレースで拡張できない可能性があります)。一般的な解決策は、関数がバッファーのサイズを指定する2番目の引数を取り、バッファーが小さすぎる場合はエラーコードを返すことです。理想的には、エラーコードはユーザーに必要なバッファーの大きさを知らせ、ユーザーが自分でバッファーを再割り当てして関数を呼び出すことができるようにします。たとえば、snprintf(この問題がある)のマニュアルページから:

関数snprintf()およびvsnprintf()は、サイズバイト(終了ヌルバイト('\ 0')を含む)を超えて書き込みません。この制限のために出力が切り捨てられた場合、戻り値は、十分なスペースが使用可能であった場合に最終文字列に書き込まれたであろう文字数(終了ヌルバイトを除く)です。したがって、size以上の戻り値は、出力が切り捨てられたことを意味します。

于 2012-10-27T18:58:20.620 に答える
2

fill_the_bufferバッファサイズを関数に渡す必要があります。バッファが十分に大きくない場合、関数はエラー値(f / e -1)を返す必要があります。成功した場合、関数は書き込まれたバイト数を返すことができます。この方法は、C言語の一般的な方法です。

于 2012-10-27T18:53:30.890 に答える
2

関数は 、バッファを最初にディメンション化する方法、および/またはバッファを いつ再割り当てするか、およびそのfill_the_buffer()量を知るのにはるかに適しているようです。

したがって、APIを変更することが適切な場合があります。

char * fill_the_buffer()
または多分
char * fill_the_buffer(size_t max_amount_caller_wants)

fill_the_buffer()の呼び出し元は、関数によって返されたバッファーを破棄する責任がありますが、割り当てとディメンション化は関数のロジックに任されます。

このアプローチは通常、実装の詳細を下位レベルに残し、上位レベルを読みやすくするという考え方に従います。

于 2012-10-27T18:56:24.393 に答える
0

空きメモリの割り当てに問題がない場合は、
を使用してプログラムの最初に初期サイズを割り当ててmallocください(この初期割り当てを適切に推測してください)。その後、fill_the_bufferより多くのメモリを割り当てる必要がある場合があります。または、割り当てられたすべてのメモリが必要ない場合もあります。最初のケースでは、いくつかのステップで適切な量のメモリ(アプリケーションと使用可能なRAMに応じて)を割り当て(たとえば、リークごとに10MB)、さらにメモリが必要になるまでバッファの充填を再開し、バッファがいっぱいになるまでこれを繰り返すことができます。realloc2番目のケースでは、バッファに割り当てられたメモリのサイズを単純に減らすことができます。
ただし、使用には注意してくださいrealloc特にバッファのサイズを増やしたい場合は、通常大きなオーバーヘッドが発生するためです(空きメモリの十分な大きさの部分を見つけて、古いデータをすべて新しい部分にコピーし、古いセクションを解放する必要があります)。

于 2012-10-27T19:06:59.330 に答える