2012-03-20 14 views
37

などの機能を、なぜ私は、不思議:
-memset
-memmov
-memchr
-memcpy
memset、memchr ...のようなメモリ関数はstring.hにありますが、stdlib.hには別のmem関数がありません。

が、そこにいるところstring.hのヘッダファイルに存在しますが、ないSTDLIB.Hファイルに他の標準的なメモリは動的メモリ割り当てとして機能する:malloc、calloc、realloc、free。

1つのヘッダーに結合する方がいいでしょうか?あなたはそれについてどう思いますか? 私は理解していない、なぜメモリ関数の1つのセットが他から分離され、文字列ヘッダー(string.h)に存在します。

+1

これは、使用しているCライブラリの実装上の問題のようです。他のCライブラリは、memcpyをstdlibに移動することを選択するかもしれません。 – AgA

+1

'malloc'と家族は動的メモリ割り当てを扱います。 'memcpy'と家族は一連のバイトを処理します。 'strcpy'と家族もやや異なった方法でバイト列を扱います。 –

+5

@AgA:CライブラリがISO規格に準拠している場合、 'memcpy'は' stdlib.h'ではなく 'string.h'になります。 – Blastfurnace

答えて

30

実際にはstring.hは文字列だけでなく文字配列を扱う関数を宣言する標準ヘッダーとして定義されているためです。 memcpymemsetのような関数は、文字配列型のオブジェクトの最初の要素へのポインタとして扱われる引数をとります。

(C99、7.21.1p1)ヘッダ< string.hの>は一種類と複数の関数を宣言し、文字型と文字型の配列 として扱われ、他のオブジェクトの配列を操作するためのマクロ有用な1つを定義します。

+2

しかしmemset、memchr、memmov、memcpyなどのメソッドはvoid *型で動作し、実際にはメモリはcharではありませんが、そうですか? –

+2

オブジェクトポインタの型を渡すことはできますが、配列要素は実際に 'unsigned char'型のように解釈されます。 (C99、7.21.1p3) – ouah

+1

また、 'void *'に関しては、K&R C(pre-Standard C)では 'void '型がなく、' memcpy'や 'memset'のような関数のパラメータは' char * '型であり、' void * 'ではありません。 – ouah

10

私は実際にはstring.hの機能を「メモリ」機能とは考えていません。代わりに、それらはメモリのシーケンス内に含まれるデータを操作するため、それらを「配列」関数と考えることにします。対照的に、malloc(および他のもの)は、実際には、メモリの領域内でデータを操作するのではなく、割り当てなどのメモリサービスを提供する。

特に、string.hの関数は、メモリの割り当てや割り当て解除、または任意の形式のメモリ管理を処理しません。 char * strerror(int)のような関数であっても、新しい文字列全体を作成するように見える場合でも、戻り値は実際には静的に割り当てられた文字列であるため、割り当ては行われません。他の関数はメモリブロックへのポインタを返す可能性がありますが、実際にはパラメータの1つ(例:memcpy)です。または、サブストリング(strtok)の開始位置へのポインター、または比較を表す整数(memcmp)を返します。

一方、stdlib.hは実際にはメモリではありません。 stdlib.hの設計は、多数のプログラムが必要とするであろう汎用動作を提供することである。メモリ機能は、このような基本的な動作の例に過ぎない。しかし、exitsystemのような他の関数も良い例ですが、メモリには適用されません。

今IMO string.h内に配置されている可能性がstdlib.hでいくつかの機能、特に、様々な変換関数(mbstowcswcstombsatoistrtod、等)、及び多分bsearchqsort機能があります。これらの関数は、string.h関数と同じ原則に従います(配列上で動作し、新たに割り当てられたメモリブロックを返さないなど)。

しかし、それはmallocrealloccallocfree機能をmem*機能を組み合わせることには意味の多くを作っても、実用的な観点から、C標準ライブラリは次のように再編成するつもりはありませんされます。そのような変更は間違いなくコードを壊すでしょう。また、stdlib.hstring.hはずっと長い間存在していて、そのような有用で基本的なライブラリであり、変更がおそらくほとんどの(または少なくとも多くの)Cコードを破壊する可能性があります。

3

標準Cより前のこれらの関数は実際には別の場所で定義されていましたが、stdlib.hやその他の標準ヘッダーではなく、memory.hに定義されていました。あなたのシステムにまだ存在するかもしれませんが、それはOS X上ではまだまだあります(今日のように)。 (ライセンスヘッダなし)OS X 10.11に

memory.h

#include <string.h> 

ファイル全体が後方プレ標準Cプログラムとの互換性を保持するために、string.hをINGの」だけ#includeあります。

関連する問題