動的メモリ管理と一般的なエラー

存在の意味

私たちの記憶開発方法は主に次のとおりです。

int a=0;//开辟4字节的空间
int arr[5]={
    
    0};//开辟20字节的空间

この開発にはいくつかの問題があり
ます。変数開発はメモリ内のスタックにあるため、スペースは比較的限られています。
固定メモリスペースしか開くことができないため、その後の調整には不便です。
特定のシナリオでは、開く必要のあるメモリサイズを取得できません。

そのため、特定の状況で問題を解決するために、動的にスペースを開放しました。

1.必要なメモリサイズまたは変更されたメモリサイズを判別できません
2.操作用により大きなスペースを開くことができます(動的に開かれたメモリスペースはメモリヒープ上にあり、スペースは変数が存在するスタックスペースよりも大きくなります) )に位置して
3しかし、それは非常に良いですが、動的に開かれたメモリ空間が、それ以外の場合は深刻なメモリリークが発生します、我々は適用人が積極的に解放する必要がありますが。

メモリリークは、特にサーバーコードなど、継続的に実行されている場所では、非常に致命的な問題であると言えます。深刻な場合、サーバーは麻痺します。

  1. スタック領域(スタック):関数を実行すると、関数内のローカル変数のストレージユニットをスタック上に作成できます。これらの
    ストレージユニットは、関数の実行時に自動的に解放されます。スタックメモリ割り当て操作は、プロセッサの命令セットに組み込まれています。これは非常に効率的ですが、割り当てられるメモリ容量には
    制限があります。スタック領域には、主に、実行中の関数に割り当てられたローカル変数、関数パラメーター、戻りデータ、戻りアドレスなどが格納されます。
  2. ヒープ:通常、プログラマーによって割り当てられて解放されます。プログラマーがそれを解放しない場合、プログラムの終了時にOSによって再利用される可能性があります。割り当て方法は
    、リンクリストにています。

関連機能

1.malloc

C言語は、動的メモリ開発のための機能を提供します。

void* malloc(size_t  size);
//size是指开辟空间的字节数

この関数は、メモリから継続的に使用可能なスペースに適用され、このスペースへのポインタを返します。

1.開発が成功すると、開いているスペースへのポインタが返されます。失敗した
場合はNULLを返します。2。戻り値は一般的なものであるため、自分で決定できます。
3.パラメータサイズが0の場合、mallocの動作は標準で定義されていません。

通常、mallocは次のように使用します。

int* arr=(int*)malloc(4);

int a[5]={
    
    0};
char* arr1=(char*)malloc(sizeof(int)*5);
//malloc搭配sizeof更方便
//malloc一般使用是带一个强制类型转换

2.無料

C言語は、動的メモリの解放と回復に特別に使用される別の関数フリーを提供します。関数プロトタイプは次のとおりです。

void free(void*arr);

キーポイント:

free関数は、動的に割り当てられたメモリを解放するために使用されます。
1.パラメーターarrが指すスペースが動的に開かれていない場合、free関数の動作は定義されていません。
2.パラメーターarrがNULLポインターの場合、関数は何もしません。

int* arr=(int*)malloc(4);
free(arr);

int a[5]={
    
    0};
char* arr1=(char*)malloc(sizeof(int)*5);
free(arr1);

3.calloc

ヒープメモリを開くことはmallocと同じですが、開いているすべてのスペースを0に初期化する
点が異なります。彼とmallocの正式なパラメータには違いがあり、注意が必要です。

void* calloc (size_t num, size_t size);
//开辟num个大小为size字节的空间

1.関数の機能は、サイズサイズのnum要素のスペースを開き、スペースの各バイトを0に初期化することです。
2.関数mallocとの違いは、callocは、アドレスを返す前に、要求されたスペースの各バイトをすべて0に初期化することです。

int *arr = calloc(10, sizeof(int));
free(arr);
//不用的时候就一定要free掉内存,虽然我们的代码很短,
//在程序结束自动释放,但是大项目就不一定了。

ここに画像の説明を挿入します

4.realloc

realloc関数の出現により、動的メモリ管理がより柔軟になります。
彼は、私たちが申請するヒープスペースのサイズを変更できます。

void* realloc (void* ptr, size_t size);
//ptr 是要调整的内存地址
//size 调整之后新大小
//返回值为调整之后的内存起始位置。
int *arr = calloc(10, sizeof(int));
int *p=realloc(arr,20);
free(p);
//将calloc出来的40字节变成了20字节

注:
reallocがスペースのサイズを変更する状況は2つあり
ます。1。スペースの開始位置は変更されません(元のスペースは十分に大きい)
ここに画像の説明を挿入します
2。開始位置が変更されます
ここに画像の説明を挿入します

よくある間違い

1.空白なし

INT_MAXはマクロ定義です。つまり、通常の状況では完了できない最大メモリスペースをオペレーティングシステムに適用できるため、mallocはNULLを返し、未定義の動作であるnullポインタを逆参照します。

void test(){
    
    
int *p = (int *)malloc(INT_MAX);
*p = 10;
free(p);
}

2.範囲外

境界を越えることは未定義の振る舞いです。動的に開かれるか、スタックスペース内の変数であるかに関係なく、境界を越えてアクセスすることはできません。

int* arr=(int *)malloc(sizeof(int)*4);
for(int i=0;i<=4;i++){
    
    
	*(p+i)=1;
}

3.非動的開発フリー

freeは、動的に割り当てられたメモリのみをサポートします。それ以外の場合は、エラーが報告されます

int arr[5]={
    
    0};
free(arr);

4.完全にはリリースされていません

リリースが不完全で、メモリリークが発生します

int *p = (int *)malloc(100);
p++;
free(p);//p不再指向动态内存的起始位置

5.リリースを繰り返します

このメモリスペースの繰り返しの解放は、未定義の動作です。

int *arr = calloc(10, sizeof(int));
int *p=realloc(arr,20);
free(p);
free(arr);

6.空き容量がありません

動的に作成されたメモリスペースは、使用しないときは解放する必要があります。

int* p=(int*)malloc(12);

おすすめ

転載: blog.csdn.net/zhaocx111222333/article/details/114630735