malloc関数,free関数,calloc関数およびrealloc関数の詳細

5469 ワード

メモリ領域は、スタック、スタック、静的ストレージ領域、定数ストレージ領域に分けることができます.ローカル変数、関数パラメータ、一時変数はスタック上でメモリを取得し、コンパイラによって自動的に実行されます.
C標準関数ライブラリには、malloc関数、free関数、calloc関数、realloc関数など、スタック上のメモリ管理を実現するための多くの関数が用意されています.これらの関数を使用するには、ヘッダファイルstdlibを含める必要があります.h
1.malloc関数
malloc関数は、指定したバイトのメモリ領域をスタックから取得できます.その関数は次のように宣言されます.
void * malloc(int n);
ここで、パラメータnは、割り当てが要求されるバイト数である.関数の実行に成功すると、mallocはメモリ領域を取得するヘッダアドレスを返します.関数の実行に失敗した場合、NULLが返されます.malloc関数値のタイプはvoid型ポインタであるため、その値タイプを変換して任意のタイプポインタに割り当てることができ、このタイプポインタを操作することでスタックから得られたメモリ空間を操作することができる.
malloc関数が割り当てられたメモリ領域は初期化されていないことに注意してください.したがって、通常、メモリ領域を使用する場合、別の関数memsetを呼び出してフル0に初期化します.memset関数の宣言は次のとおりです.
    void * memset (void * p,int c,int n) ;
この関数は、指定されたメモリ領域をバイト単位で指定された文字cにすることができる.ここで、pはクリアするメモリ空間のヘッダアドレスであり、cは設定する値であり、nは操作されるメモリ空間のバイト長である.memsetで0をクリアする場合は、変数cの実パラメータは0になります.malloc関数とmemset関数の操作文は、一般的に次のようになります.
int * p=NULL;
p=(int *)malloc(sizeof(int));
if(p==NULL)
    printf(“Can’t get memory!”);
memset(p,0,siezeof(int));
注意:malloc関数で得られたスタックメモリはmemset関数を使用して初期化する必要があります.
demo:
#include
#include
#include
int main()
{
     int * p=NULL;
     p=(int *)malloc(sizeof(int));
     if(NULL==p){
         printf("Can't get memory!");
         return -1;
     }
     printf("%d",*p);//割り当てられたスペースの値を出力する
     memset(p,0,sizeof(int));//pが指す空間をクリアする
     printf("%d",*p);//memset関数を呼び出した結果の出力
     *p=2;
     printf("%d",*p);
     return 0;
}
2.free関数
スタックから取得したメモリ領域は、プログラムが終了した後も自動的に解放されず、プログラマが自分で管理する必要があります.1つのプログラムが終了すると、スタックから取得したすべてのメモリ領域が安全に解放されることを保証する必要があります.そうしないと、メモリが漏洩します.たとえば、上のdemoでメモリの漏洩が発生します.
free関数はメモリを解放する機能を実現します.関数は次のように宣言されます.
void free (void * p);
パラメータがvoidポインタであるため、free関数は任意のタイプのポインタ実パラメータを受け入れることができる.
ただし、free関数はポインタが指す内容を解放するだけで、ポインタは元の方向を指しています.この場合、ポインタは野ポインタであり、このときポインタを操作すると予想できないエラーが発生します.安全な方法は、free関数を使用してポインタが指す空間を解放した後、ポインタの値をNULLに設定することです.したがって、上記のdemoについてはreturn
文の前に次の2行の文を加えます.
free(p);
p=NULL;
注意:malloc関数を使用して割り当てられたスタックスペースは、プログラムが終了する前に解放する必要があります.
3.calloc関数
calloc関数の機能はmalloc関数の機能と似ており,いずれもスタックからメモリを割り当てる.関数は次のように宣言されます.
void *calloc(int n,int size);
関数の戻り値はvoid型ポインタです.実行に成功すると、関数はスタックからsize X nのバイト空間を取得し、その空間のヘッダアドレスを返します.実行に失敗した場合、関数はNULLを返します.この関数はmalloc関数と著しく異なり,calloc関数で得られたメモリ空間は初期化され,その内容はすべて0であった.calloc関数は配列申請空間に適しており、sizeを配列要素の空間長に設定し、nを配列の容量に設定することができる.
demo:
#include
#include
#define SIZE 5
int main()
{
     int * p=NULL;
     int i=0;
//pスタックからSIZE個int型スペースを割り当てる
     p=(int *)calloc(SIZE,sizeof(int));
    if(NULL==p){
         printf("Error in calloc.");
         return -1;
     }
//p指向のSIZE個int型空間に値を与える
     for(i=0;i
         p[i]=i;
//各空間の値を出力する
     for(i=0;i
         printf("p[%d]=%d",i,p[i]);
     free(p);
     p=NULL;
     return 0;
}
実行結果:
ヒント:calloc関数の割り当てられたメモリも自分で解放する必要があります.
4.realloc関数
realloc関数の機能はmalloc関数とcalloc関数の機能よりも豊富で、メモリ割り当てとメモリ解放の機能を実現することができ、その関数は以下のように宣言されています.
void * realloc(void * p,int n);
ここで、ポインタpは、malloc関数、calloc関数、またはrealloc関数によって空間が割り当てられるポインタであるスタックメモリ空間を指す必要がある.realloc関数は、ポインタpが指すメモリブロックのサイズをnバイトに変更します.nがpの前に指す空間サイズ以下である場合.元の状態を保つ.nが元のpの前に指す空間サイズより大きい場合、システムは再びpのためにスタックからnのサイズのメモリ空間を割り当て、同時に、元の空間を指す内容を新しいメモリ空間に順次コピーし、pの前に指す空間は解放される.relloc関数が割り当てる空間も初期化されていません.
注意:malloc関数、calloc関数、realloc関数を使用して割り当てられたメモリ領域は、free関数またはポインタパラメータがNULLのrealloc関数を使用して解放されます.
【FROM MSDN&&百科】
【FROM:http://baike.baidu.com/view/736230.htm】
プロトタイプ:
void * realloc ( void * ptr, size_t size );

#includeまたは#include
ポインタ名=(データ型*)realloc(メモリサイズを変更するポインタ名、新しいサイズ).//新しいサイズは必ず元のサイズより大きくしなければなりません.そうしないと、データが失われます.
Pointer to a memory block previously allocated with malloc, calloc or realloc, or a null pointer (to allocate a new block).
現在のポインタに十分な連続空間があるかどうかを判断し、ある場合はmem_を拡大します.addressが指すアドレスでmem_addressは、スペースが足りない場合はnewsizeで指定したサイズに従ってスペースを割り当て、既存のデータを最初から最後まで新しい割り当てられたメモリ領域にコピーし、元のmem_を解放します.addressはメモリ領域を指し、新しく割り当てられたメモリ領域のヘッダアドレスを返します.すなわち、メモリブロックのアドレスを再割り当てする.
百科事典でまとめられたreallocの使い方について
1.reallocが失敗した場合はNULLに戻る
2.reallocが失敗した場合、元のメモリは変更せず、解放も移動もしません
3.元のメモリの後ろに十分な余剰メモリがある場合、reallocのメモリ=元のメモリ+余剰メモリ、reallocは元のメモリのアドレスを返します.元のメモリの後ろに十分なメモリがない場合は、reallocは新しいメモリを申請し、元のメモリデータを新しいメモリにコピーし、元のメモリがfreeされ、reallocは新しいメモリのアドレスを返します.
4.sizeが0の場合、効果はfree()に等しい.ここで注意しなければならないのは、ポインタ自体のみを解放することです.例えば、2次元ポインタ**aに対して、aに対してreallocを呼び出すと1次元しか解放されず、メモリの漏洩に注意して使用します.
5.reallocに渡されるポインタは、malloc()、calloc()、またはrealloc()によって以前に割り当てられた、またはNULLである必要があります.
6.reallocに渡されるポインタは、mallocに等しい空であってもよい.
demo:
#include
#include
int main()
{
     int * p=NULL;
     p=(int *)malloc(sizeof(int));
     *p=3;
     printf("p=%p",p);
     printf("*p=%d",*p);
     p=(int *)realloc(p,sizeof(int));
     printf("p=%p",p);
     printf("*p=%d",*p);
 
     p=(int *)realloc(p,3*sizeof(int));
     printf("p=%p",p);
     printf("*p=%d",*p);
//pが指す空間を解放する
     realloc(p,0);
     p=NULL;
 
     return 0;
}