web-dev-qa-db-ja.com

mallocを使用するタイミングと理由

さて、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;だけを使用できるのに、メモリを割り当てる必要があるのはなぜですか?

46
pr1m3x

mallocは、動的メモリ割り当てに使用されます。前述のように、それは動的割り当てであり、実行時にメモリを割り当てます。たとえば、コンパイル時にメモリの量がわからない場合。

1つの例でこれをクリアする必要があります。最大20人の生徒がいることを知っているとしましょう。したがって、静的な20個の要素を持つ配列を作成できます。アレイには最大20人の生徒を収容できます。しかし、学生数がわからない場合はどうでしょうか?最初の入力は生徒数です。 10、20、50、またはそれ以外の場合があります。ここで、入力n =実行時の生徒数を取得し、mallocを使用してその量のメモリを動的に割り当てます。

これはほんの一例です。動的な割り当てが必要なこのような多くの状況があります。

Manページ malloc(3) をご覧ください。

43
taskinoor

mallocを使用するのは、現在のブロックの実行期間を超えて存在しなければならないオブジェクトを割り当てる必要がある場合(コピーオンリターンも高価になる場合)、またはメモリを割り当てる必要がある場合そのスタックのサイズ(すなわち:3mbローカルスタック配列はbadアイデアです)。

C99がVLAを導入する前に、必要動的にサイズ調整された配列の割り当てを実行しますが、多くのシステムで使用されるツリー、リスト、キューなどの動的データ構造の作成に必要です。おそらくもっと多くの理由がありますが、これらはほんのわずかです。

21
Necrolis

例の構造を少し拡張して、これを考慮してください:

#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を渡すことで、構造全体を渡すことはしません。この構造を参照するメモリ内のアドレスのみを渡します。渡されるデータの量は少ないため(ポインターのサイズ)、操作は高速です。

今、これを知って、数千または数万のレコードのセットを作成および管理しなければならないプログラム(学生情報システムなど)を想像してください。構造全体を値で渡すと、各レコードへのポインタを渡すよりも、データのセットを操作するのに時間がかかります。

17
ArcticPhoenix

malloc =メモリ割り当て。

他のプログラミング言語を使用している場合、「新しい」キーワードを使用した可能性があります。

MallocはCでもまったく同じことを行います。パラメーター、割り当てる必要のあるメモリのサイズ、および最初のメモリブロックを指すポインター変数を返します。

メモリ内に作成したメモリブロック全体。例-

int *p = malloc(sizeof(int)*10);

ここで、* pは、メモリ上に予約されている結果の20整数ブロックの最初のブロックを指します。

++および-演算子を使用して、各ブロックを走査できます。ではごきげんよう。

4
Acn

さまざまな側面を考慮してこの質問に取り組みましょう

サイズ

mallocを使用すると、単にstudent p;またはint x[n];を使用して割り当てられたものよりもはるかに大きなメモリ空間を割り当てることができます。 mallocである理由は、ヒープにスペースを割り当て、もう一方がスタックにスペースを割り当てる

Cプログラミング言語は、メモリを静的、自動、また​​は動的に管理します。静的期間変数は、通常プログラムの実行可能コードとともにメインメモリに割り当てられ、プログラムの存続期間中持続します。自動期間変数は、スタックに割り当てられ、関数が呼び出されて戻るときに行き来します。静的期間および自動期間変数の場合、割り当てのサイズはコンパイル時の定数でなければなりません(可変長の自動配列[5]の場合を除く)。必要なサイズが実行時までわからない場合(たとえば、任意のサイズのデータ​​がユーザーまたはディスクファイルから読み取られる場合)、固定サイズのデータ​​オブジェクトの使用は不適切です。 ( ウィキペディアから

範囲

通常、宣言された変数は、宣言されたブロックの後に削除/解放されます(スタックで宣言されます)。一方、mallocを使用して割り当てられたメモリを持つ変数は、手動で解放されるまで残ります。

これはまた、関数で変数/配列/構造を作成し、そのアドレスを返すことができないことを意味します(ポイントしているメモリが解放される可能性があるため)。コンパイラーは、警告を出すことでこれについて警告しようとします:

警告-ローカル変数「matches」に関連付けられたスタックメモリのアドレスが返されました

詳細については こちらをお読みください

サイズの変更(realloc

ご想像のとおり、通常の方法では不可能です

エラー検出

メモリを割り当てることができない場合:mallocNULLを返しますが、通常の方法ではプログラムが終了し、プログラム内で簡単にキャッチして処理できます。

将来的に文字列コンテンツに変更を加える

char *some_memory = "Hello World";のような文字列を作成する場合、文字列定数として保存され、保存されるメモリは読み取り専用であるため、some_memory[0] = 'h';を実行できません。代わりにmallocを使用する場合、後で内容を変更できます。詳細については、 この回答を確認してください

可変サイズの配列に関する詳細については、 これを見てください

1
Daksh Shah

この例では、まったく役に立たないようです。しかし、ソケットまたはファイルIOを使用しており、実行中にのみ抑止できる可変長からパケットを読み取らなければならないことを想像してください。静的配列を作成することもできますが、これにより、コンパイル中に抑止されるクライアント制限が与えられます。

0
DipSwitch