C言語 結局ややこしいのは二次元配列とvoidポインタ

twcritique
色々聞くと構文はやって、ポインタも分かって、関数も構造体もきれるとなると、分からなくなるのはライブラリ使う前の配列系の記述やらクリシェやらおまとめ

なんでmalloc

C言語では、malloc関数を使ってヒープ領域からメモリブロックを確保する。プログラムはmallocの戻り値であるポインタを使って、そのメモリブロックにアクセスする。メモリブロックが不要になったら、そのポインタをfreeに渡して解放し、他の用途に再利用できるようにする。
malloc – Wikipedia

ヒープではなくCのスタックフレームから実行時に動的にメモリを確保するライブラリルーチンもある(Unix系の alloca()[4]、Microsoft Visual C++におけるCランタイムライブラリの _malloca()[5] など)。

malloc() 関数は、 size バイトのメモリを割り当てます。 割り当てられた空間は (可能なポインタ強制の後で) あらゆるタイプのオブジェクトが保存できるように適切に調整されます。
malloc(3) manページ

イメージしづらい、void型のポインタ

malloc() 関数と calloc() 関数は、成功した場合は割り当てられたメモリへのポインタを返し、 それ以外の場合は NULL ポインタを返し errno を ENOMEM に設定します。
malloc(3) manページ

ポインタと言っているが、注意が必要

ANSI Cにおいてmallocが返すのは、void型へのポインタ (void *) であり、そのポインタが指す領域のデータ型が不明であることを示している。
malloc – Wikipedia

キャストオフ

malloc関数で返却されるポインタの型は、malloc関数を使用する場所ごとに異なります。そのため、型の指定が出来ません。よって、この「void *」で「どのような型にするかは後で決めてください。とりあえずポインタを返しますよ。」と宣言するのです。しかし、使用するときには、次の使用例のように、本来の目的の型でキャストしてやるべきでしょう。

ダブルポインタ

このとき、ダブルポインタは二次元配列とは、別なものであるにも関わらず、参照の方法である D[5][5] = 55; は二次元配列の参照と、まったく区別できない。だからこれら2つを区別して呼ぶことが大変重要である。

2次元配列は1次元配列と同じように連続したメモリの領域を確保する。
ポインタの配列の場合、2次元目の配列(1次元目の配列が指す先)はメモリ上のどこかにあり、他の2次元目の配列とは連続している必要は無い。

そして、割り当てと初期化は別

mallocはメモリブロックを確保して返すが、その領域は初期化されていない。
malloc – Wikipedia

C++でのmallocは禁じ手の扱いである。
malloc – Wikipedia

現在のメモリ割り当ての実装は、 個別のゲルマニウムトランジスタで作成された、 20 ビットバイナリコンピュータに取り付けられたドラムの ファイルシステムとしてスタートしました。
malloc(3) manページ

以降は、二次保存域ではなく、一次保存域を操作するようになりました。 この新しい形態と機能は FreeBSD 2.2 ではじめて登場しました。
http://sts.kahaku.go.jp/diversity/document/system/pdf/003.pdf
https://ja.wikipedia.org/wiki/CSIRAC

The present implementation of malloc() started out as a filesystem on a drum attached to a 20-bit binary challenged computer built with discrete germanium transistors, and it has since graduated to handle primary storage rather than secondary.
malloc()

消えてた記述

メモリの確保が行われるのは、mallocが管理しているリソースが足りなくなった時だ。常にOSからメモリを確保している訳ではない。 mallocはOSからメモリを確保しないし、freeはOSにメモリを解放しないと覚えていた方がまだマシだ。

https://matome.naver.jp/odai/2158417148438265801
2020年03月17日