次のコードを説明していただけますか?
str = (char *) malloc (sizeof(char) * (num+1));
- ここで何を
malloc
していますか? - なぜ
num + 1
使用されるのですか?
malloc
ヒープにメモリのチャンクを割り当て、それへのポインタを返す関数です。new
多くの言語の演算子に似ています。この場合、任意の長さの期間存続し、任意のサイズを持つことができるメモリのブロックを作成しています。それ自体はかなり詳細なものであり、説明がやや難しく、別の質問が必要です。
は、文字列の末尾にあるヌル ターミネータnum + 1
を補正します。文字列は多くの場合、それらの長さを知る必要があり、C の伝統では、文字列の末尾に追加の文字 (常に特殊文字) 用のスペースを割り当てることになっています。これにより、文字列を処理する関数が文字列のサイズを自動的に決定できるようになります。たとえば、文字列の長さを知らずに文字列のすべての文字に対して何かをしたい場合は、次のようにすることができます。\0
const char *ptr = str;
while (*ptr != '\0') {
process(*ptr);
ptr++;
}
malloc
メモリ割り当て用です。
num + 1
null-terminator - を許可することです\0
。
前文: 信じられない! 私が C の基礎を教えられたとき、この種の表現に困惑しました (しゃれた意図はありません)。これが、「コードの解析」セクションで非常に詳細に説明する理由です。
最初の問題はコードの解析です
str = (char *) malloc (sizeof(char) * (num+1));
C/C++ を使用する場合、この種の式の解析は必須であるため、式をそのコンポーネントに分解します。ここで最初に目にするのは、次のようなものです。
variable = (expression) function (expression) ;
初めて見たときは、「関数呼び出しの左右両方にパラメータを置いて関数を呼び出せるプログラミング言語があるなんて信じられない!」と思いました。
実際、この行は次のように読む必要があります。
variable = function_a (function_b (expression)) ;
どこ :
expression is sizeof(char) * (num+1)
function_b is malloc
function_a is a cast operator
すでに他の場所で説明したように、C スタイルのキャスト演算子はより類似しています。
(function_a) expression
自然よりも
function_a(expression)
これは、コード行全体の奇妙さを説明しています。
C++ では両方の表記を使用できますが、上記の表記の代わりに static_cast、const_cast、reinterpret_cast、または dynamic_cast を使用する必要があります。C++ キャストを使用すると、上記のコード行は次のようになります。
str = static_cast<char *> ( malloc (sizeof(char) * (num+1)) ) ;
sizeof は演算子です。型に作用する関数のように考えることができます。タイプをパラメーターとして渡すと、そのサイズがバイト単位で示されます。
したがって、次のように書くと:
size_t i = sizeof(char) ;
size_t j = sizeof(int) ;
おそらく (32 ビット Linux では) i の値は 1、j の値は 4 です。malloc での使用は、「少なくとも 100 メートルは欲しい」ではなく、「長さ 4 メートルの車を 25 台置ける十分なスペースが欲しい」と言っているようなものです。
Malloc のパラメーターは size_t、つまり符号なし整数です。サイズをバイト単位で指定し、成功した場合は、配列として使用するのに十分な大きさの割り当てられたメモリのアドレスを返します。例えば:
int * p = (int *) malloc (25 * sizeof(int)) ;
次に、 p は、インデックスがゼロからマイナス1のサイズになる配列内にあるかのように、25個の整数を並べて配置できるメモリを指します。例えば:
p[0] = 42 ; // Ok, because it's the 1st item of the array
p[24] = 42 ; // Ok, because it's the 25th item of the array
p[25] = 42 ; // CORRUPTION ERROR, because you are trying to
// use the 26th item of a 25 items array !
注:ポインター演算もありますが、これは質問の範囲を超えています。
C スタイルの文字列は、他の言語の文字列とは多少異なります。文字列の各文字は任意の値にすることができますが、ゼロではありません。ゼロ (\0 とも表記) は ac 文字列の終わりを示すためです。
別の言い方をすれば、c-string のサイズは決してわかりませんが、\0 文字を検索することで、それがどこで終了するかを知ることができます (ちなみに、これがバッファー オーバーフローやスタック破損の原因の 1 つです)。
たとえば、文字列 "Hello" は 5 文字のようです。
"Hello" seems to be an array containing 'H', 'e', 'l', 'l' and 'o'.
しかし、実際には 6 文字あり、最後の文字 ZERO はエスケープ文字 \0 を使用して示されます。したがって:
"Hello" is an array containing 'H', 'e', 'l', 'l', 'o' and 0.
これは、「num」文字の文字列に十分なスペースを割り当てたい場合、代わりに「num + 1」文字を割り当てることを説明しています。
mallocはメモリを割り当てます。
num+1 num は文字列内の文字数であり、null ターミネータの場合は +1 です。
この場合の Malloc は、num+1 倍の sizeof(char) バイトを割り当てています。これは、要素の配列を割り当てたい場合の標準的な方法です。sizeof(char) の char は通常、割り当てられる配列の型に置き換えられます。
この例では厳密に言えば sizeof(char) は必要ありません。C標準ではサイズが1であることが保証されているため、1を掛けるだけです。
malloc は、char の配列 (この場合) をヒープに割り当てます。
array の長さは num+1 になりますが、保持できる最長の文字列は 'num' の長さです。これは、C の文字列には末尾の null バイトが必要なためです。
Malloc はメモリを割り当てます。この場合、長さ num の文字列 str に対してです。(char *) は str の型です。 sizeof(char) は各文字に必要なバイト数です。+1 は文字列の末尾のヌル文字を表し、通常はゼロです。
Malloc は、メモリを割り当てるための呼び出しです。
上記のコードは、num + 1 文字のスペースを割り当てます。おそらく num 文字の文字列があり、コードの作成者がヌル ターミネータ用のスペースを追加しています。
呼び出しの後、str は、割り当てられたメモリ ブロックの先頭を指します。
このコードは、char 型の num + 1 個の値を保持できるメモリのチャンクを割り当てようとします。したがって、チャットが 1 バイトで num が 10 の場合、11 バイトのメモリを割り当てて、そのメモリへのポインタを返そうとします。
+1 が使用されるのは、プログラマーが num 文字の文字列 (文字配列) を格納する必要があり、終端の '\0' (ヌル) 文字を格納するために追加の文字が必要なためです。C/C++ で。文字列は、慣例により、ヌル文字で終了します。
malloc はヒープからメモリを割り当て、それへのポインタを返します。コンパイル時にどれだけのメモリが必要になるかわからない場合に便利です。
(num+1) の理由については、コードが何を行っているかによって異なります。おそらく num は文字列内の文字数であり、+1 は最後の NUL ターミネータ バイトです。ただし、その場合に sizeof(char) が何になるかはわかりません。
sizeof(char)
安全です。1 文字が 1 バイトであると想定すべきではありません。
私の質問は、malloc が何をするかわからない場合、プログラミングを何をしているのですか?
man malloc
Linux システム上。Windows の場合。知るか?おそらく17回のマウスクリックです。