8

重複の可能性:
malloc と calloc の c の違い
calloc には 2 つのパラメーターが必要で、malloc には 1 つしか必要ないのはなぜですか?

多くの C 関数呼び出し、特にメモリまたはファイル操作を扱うものでこれに気付きましたが、すべてが両方のパラメーターを使用しているわけではありません。たとえば、malloc には 1 つのパラメーター (必要なメモリ空間のサイズ (バイト単位)) が渡されます。一方 Calloc には、要素のサイズ (バイト単位) と要素数 (size と nmem) の 2 つのパラメーターが渡されます。これらの size および nmem パラメータを使用する関数は他にもあります。

基本的に、calloc 呼び出しは malloc(nmem size) を呼び出すのと同じ量のメモリを割り当てるため、実際に起こっていることは、アスタリスク ( ) がコンマ (,) に置き換えられることだけです。少なくとも、私が働いているより高いレベルから私が言えることはこれだけです。calloc(1, nmem size)、calloc(nmem size, 1)、calloc(nmem, size)の呼び出しとの違いはわかりません。

インスタンス calloc(1, nmem*size) の呼び出しを calloc(nmem, size) と根本的に異なるものにする、より低いレベルで実際に起こっていることはありますか?

編集: calloc と malloc の機能的な違いを知っています。パラメータに違いがある理由に興味があります。合計サイズに 2 つのサイズ パラメータを使用する関数は他にもあります (fread、fwrite など)。特定の関数には関心がありませんが、基本的に合計サイズが 2 つのパラメーターを掛け合わせたものになるのに、関数で使用される合計サイズに 2 つのパラメーターがあるのはなぜかということです。ほとんどの場合、これらの関数を使用するときは、必要なサイズを「size」パラメーターで使用し、「nmem」(場合によっては「count」など) パラメーターに「1」を使用します。

4

2 に答える 2

2

質問へのコメントcalloc()で、重要なプラットフォームのメモリ配置を改善できるようにしました。私はそれをサポートするものを見つけることができませんでした(まだ)。これは VMS/VAXC コンパイラの機能であると確信していますが、そのソースはほとんどありません。


しかし、1975 年 5 月に Unix V6 がリリースされたときに、私はそれを発見しcalloc()alloc()同時に登場しました。11 か月前にリリースされた V5 には、どちらの機能もありません。カーネルとランタイム ライブラリ (およびアセンブラーと C コンパイラー) は、アセンブリーで作成されました。

V6 リリースでは、calloc は4 行のソース コード モジュールとして実装されています。

calloc(n, s)
{
return(alloc(n*s));
}

calloc()割り当てられたメモリをクリアしません。を参照してください。V6には のページalloc()がありませんでした。ただし、次のマニュアルページmancalloc()alloc()

説明
allocfreeは、単純な汎用コア管理パッケージを提供します。 Allocにはサイズがバイト単位で指定されます。少なくともそのサイズが偶数であり、したがって任意の型のオブジェクトを保持できる領域へのポインターを返します。freeへの引数は、以前にalloc によって割り当てられた領域へのポインターです。このスペースは、さらに割り当てることができます。

言うまでもなく、allocによって割り当てられたスペースがオーバーランしたり、何らかの乱数がfree に渡されたりすると、重大な混乱が発生します。

このルーチンは、解放中のブロックを既に解放されている他のブロックと合体させる first-fit アルゴリズムを使用します。 適切なスペースがまだ空いていない場合、sbrk ( 「break (II)」を参照) を呼び出して、システムからより多くのコアを取得します。

DIAGNOSTICS使用可能なコアがない場合は-1
を 返します。

バグ
割り当てられたメモリは、クリアされるのではなくゴミを含んでいます。

NULLメモリ不足の場合でも返却されません!

calloc()は、1979 年 1 月の UNIX V7 で最初に正式に登場し、その他のいくつかの改良が行われました。

  • calloc()返されたメモリをクリアします。
  • alloc()に改名されましたmalloc()
  • realloc()現れた
  • メモリ不足またはヒープ エラーの場合、関数は「ヌル ポインター (0) を返す」
于 2012-10-12T18:15:51.810 に答える
0

たとえばcalloc(1、nmem * size)の呼び出しをcalloc(nmem、size)と根本的に異なるものにする、より低いレベルで実際に起こっていることはありますか?

物事を説明するこの試みは、純粋にlibcの実装に依存しているため、特定のlibcの作成者に感謝の意を表します。

はメモリをゼロにするのでcalloc()、理論的根拠は、を実行するときに(潜在的に)さらにいくつかのサイクルを浪費する可能性があるということであった可能性がありますmult

対照的にmalloc()、事前に計算された値を使用する機会が与えられるため、満たすのがより簡単になる可能性がある呼び出しのオーバーヘッドが削減される可能性があります。

Cは、各CPUサイクルに多大なコストがかかるときに設計されたことを忘れないでください。したがって、他の多くの「高級」言語と比較して、非常に無駄のない設計になっています。

この質問は、おそらくCデニスリッチーの作者によってよりよく答えられるでしょう。

于 2012-10-12T16:28:41.630 に答える