さて、malloc
を使用してメモリを割り当てる必要がある時期と理由がわかりません。
ここに私のコードがあります:
#include <stdlib.h>
int main(int argc, const char *argv[]) {
typedef struct {
char *name;
char *sex;
int age;
} student;
//Now I can do two things
student p;
//or
student *ptr = (student *)malloc(sizeof(student));
return 0;
}
student p;
だけを使用できるのに、メモリを割り当てる必要があるのはなぜですか?
malloc
は、動的メモリ割り当てに使用されます。前述のように、それは動的割り当てであり、実行時にメモリを割り当てます。たとえば、コンパイル時にメモリの量がわからない場合。
1つの例でこれをクリアする必要があります。最大20人の生徒がいることを知っているとしましょう。したがって、静的な20個の要素を持つ配列を作成できます。アレイには最大20人の生徒を収容できます。しかし、学生数がわからない場合はどうでしょうか?最初の入力は生徒数です。 10、20、50、またはそれ以外の場合があります。ここで、入力n =実行時の生徒数を取得し、malloc
を使用してその量のメモリを動的に割り当てます。
これはほんの一例です。動的な割り当てが必要なこのような多くの状況があります。
Manページ malloc(3) をご覧ください。
malloc
を使用するのは、現在のブロックの実行期間を超えて存在しなければならないオブジェクトを割り当てる必要がある場合(コピーオンリターンも高価になる場合)、またはメモリを割り当てる必要がある場合そのスタックのサイズ(すなわち:3mbローカルスタック配列はbadアイデアです)。
C99がVLAを導入する前に、必要動的にサイズ調整された配列の割り当てを実行しますが、多くのシステムで使用されるツリー、リスト、キューなどの動的データ構造の作成に必要です。おそらくもっと多くの理由がありますが、これらはほんのわずかです。
例の構造を少し拡張して、これを考慮してください:
#include <stdio.h>
int main(int argc, const char *argv[]) {
typedef struct {
char* name;
char* sex;
char* insurace;
int age;
int yearInSchool;
float tuitionDue;
}student;
//Now I can do two things
student p;
//or
student *p = (student *)malloc(sizeof(student));
return 0
}
C aは、参照ではなく値によって暗黙的に渡される言語です。この例では、関数に「p」を渡して処理を行うと、構造全体のコピーが作成されます。これは、追加のメモリ(特定の構造が必要とするスペースの合計)を使用し、速度が遅く、潜在的にうまくスケーリングされません(これについては1分で詳しく説明します)。ただし、* pを渡すことで、構造全体を渡すことはしません。この構造を参照するメモリ内のアドレスのみを渡します。渡されるデータの量は少ないため(ポインターのサイズ)、操作は高速です。
今、これを知って、数千または数万のレコードのセットを作成および管理しなければならないプログラム(学生情報システムなど)を想像してください。構造全体を値で渡すと、各レコードへのポインタを渡すよりも、データのセットを操作するのに時間がかかります。
malloc =メモリ割り当て。
他のプログラミング言語を使用している場合、「新しい」キーワードを使用した可能性があります。
MallocはCでもまったく同じことを行います。パラメーター、割り当てる必要のあるメモリのサイズ、および最初のメモリブロックを指すポインター変数を返します。
メモリ内に作成したメモリブロック全体。例-
int *p = malloc(sizeof(int)*10);
ここで、* pは、メモリ上に予約されている結果の20整数ブロックの最初のブロックを指します。
++および-演算子を使用して、各ブロックを走査できます。ではごきげんよう。
さまざまな側面を考慮してこの質問に取り組みましょう
malloc
を使用すると、単にstudent p;
またはint x[n];
を使用して割り当てられたものよりもはるかに大きなメモリ空間を割り当てることができます。 malloc
である理由は、ヒープにスペースを割り当て、もう一方がスタックにスペースを割り当てる
Cプログラミング言語は、メモリを静的、自動、または動的に管理します。静的期間変数は、通常プログラムの実行可能コードとともにメインメモリに割り当てられ、プログラムの存続期間中持続します。自動期間変数は、スタックに割り当てられ、関数が呼び出されて戻るときに行き来します。静的期間および自動期間変数の場合、割り当てのサイズはコンパイル時の定数でなければなりません(可変長の自動配列[5]の場合を除く)。必要なサイズが実行時までわからない場合(たとえば、任意のサイズのデータがユーザーまたはディスクファイルから読み取られる場合)、固定サイズのデータオブジェクトの使用は不適切です。 ( ウィキペディアから )
通常、宣言された変数は、宣言されたブロックの後に削除/解放されます(スタックで宣言されます)。一方、malloc
を使用して割り当てられたメモリを持つ変数は、手動で解放されるまで残ります。
これはまた、関数で変数/配列/構造を作成し、そのアドレスを返すことができないことを意味します(ポイントしているメモリが解放される可能性があるため)。コンパイラーは、警告を出すことでこれについて警告しようとします:
警告-ローカル変数「matches」に関連付けられたスタックメモリのアドレスが返されました
詳細については こちらをお読みください
realloc
)ご想像のとおり、通常の方法では不可能です
メモリを割り当てることができない場合:malloc
はNULL
を返しますが、通常の方法ではプログラムが終了し、プログラム内で簡単にキャッチして処理できます。
char *some_memory = "Hello World";
のような文字列を作成する場合、文字列定数として保存され、保存されるメモリは読み取り専用であるため、some_memory[0] = 'h';
を実行できません。代わりにmallocを使用する場合、後で内容を変更できます。詳細については、 この回答を確認してください
可変サイズの配列に関する詳細については、 これを見てください
この例では、まったく役に立たないようです。しかし、ソケットまたはファイルIOを使用しており、実行中にのみ抑止できる可変長からパケットを読み取らなければならないことを想像してください。静的配列を作成することもできますが、これにより、コンパイル中に抑止されるクライアント制限が与えられます。