malloc.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | /*
stdlib.h [malloc]
書式: void* malloc(size_t size)
機能: 動的メモリ領域の確保をする
引数: size_t size: 領域を確保するためのバイト数を指定する
戻り値: 成功すると, 確保した領域のポインタを返し
失敗すると, NULL を返す.
戻り値は, void* となっているが, これは, どんな型でも OK ということ.
使い方としては, (char *) というようにキャストする必要がある.
*/
/*
まず, 動的メモリを確保する理由だが, 例えばプログラム実行中に, 読み込んだ
画像を処理する場合は一時的に画像データを格納する箱を作る必要がある.
そのため, データを格納する場所を作成したり, 削除したりするような処理が必要
となるわけ.
malloc()で, 動的メモリを確保した後は, 必ず解放処理をしなければならない.
メモリを解放するには, free() を使う.
*/
#include <stdio.h>
#include <stdlib.h> /* malloc */
int main(void){
char *buf = NULL;
buf = (char *)malloc(100);
if(buf == NULL){
printf("メモリ確保に失敗した\n");
}
sprintf(buf, "基本的に配列と同じように扱うことができる\n");
printf("%d\n", buf[0]);
printf("%d\n", buf[1]);
printf("%d\n", buf[2]);
free(buf);
return 0;
}
|
malloc.c の実行結果は:
[cactus:~/code_c/refer]% ./malloc
-27
-97
-70
calloc.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | /*
stdlib.h [calloc]
書式: void* calloc(size_t num, size_t size)
機能: 動的メモリ領域を確保して 0 で初期化する
引数: size_t num: 確保する領域の個数
size_t size: 一つの領域のバイト数
戻り値: 成功すると, 確保した領域のポインタを返し
失敗すると, NULL を返す.
*/
/*
calloc() は 0 で初期化してくれるところが malloc() との大きな違いなので
malloc() の戻り値は int * だと calloc() と同じように 0 で初期化される.
*/
#include <stdio.h>
#include <stdlib.h> /* calloc */
int main(void){
int *mbuf = NULL;
int *cbuf = NULL;
int i, sz;
sz = 10 * sizeof(int);
mbuf = (int *)malloc(sz);
if(mbuf == NULL){
printf("メモリ確保に失敗した\n");
return -1;
}
cbuf = (int *)calloc(10, sizeof(int));
if(cbuf == NULL){
printf("メモリ確保に失敗した\n");
return -1;
}
for(i = 0; i < 10; i++){
printf("i=%d, mbuf[i]=%d, cbuf[i]=%d\n", i, mbuf[i], cbuf[i]);
}
free(mbuf);
free(cbuf);
return 0;
}
|
calloc.c の実行結果は:
[cactus:~/code_c/refer]% ./calloc
i=0, mbuf[i]=0, cbuf[i]=0
i=1, mbuf[i]=0, cbuf[i]=0
i=2, mbuf[i]=0, cbuf[i]=0
i=3, mbuf[i]=0, cbuf[i]=0
i=4, mbuf[i]=0, cbuf[i]=0
i=5, mbuf[i]=0, cbuf[i]=0
i=6, mbuf[i]=0, cbuf[i]=0
i=7, mbuf[i]=0, cbuf[i]=0
i=8, mbuf[i]=0, cbuf[i]=0
i=9, mbuf[i]=0, cbuf[i]=0
realloc.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | /*
stdlib.h [realloc]
書式: void* realloc(void *ptr, size_t size)
機能: 確保した動的メモリサイズの変更
引数: void *ptr: malloc() や calloc() で確保した領域のポインタ
size_t size: 変更したい領域のバイト数
戻り値: 成功すると, 改めて確保した領域のポインタを返し,
失敗すると, NULL を返す.
*/
/*
realloc() は, 確保された領域 (サイズ) を拡張したり縮小したりすることが
できる関数.
*/
/*
動的メモリ領域を拡張しても, データの内容が引き継がれているのが
確認できた.
*/
#include <stdio.h>
#include <stdlib.h> /* realloc */
int main(void){
char *mbuf = NULL;
char *tmp = NULL;
int sz;
sz = 20 * sizeof(char);
mbuf = (char *)malloc(sz);
if(mbuf == NULL){
printf("メモリ確保に失敗した\n");
return -1;
}
sprintf(mbuf, "realloc test\n");
sz = 100 * sizeof(char);
tmp = (char *)realloc(mbuf, sz);
if(tmp == NULL){
printf("メモリ確保に失敗した\n");
free(mbuf);
return -1;
}else{
mbuf = tmp;
}
/* データが保持されていることを確認 */
printf("%s", mbuf);
printf("%c\n", mbuf[0]);
printf("%c\n", mbuf[1]);
printf("%c\n", mbuf[2]);
free(mbuf);
return 0;
}
|
realloc.c の実行結果は:
[cactus:~/code_c/refer]% ./realloc
realloc test
r
e
a
free.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | /*
stdlib.h [free]
書式: void free(void *ptr)
機能: 確保した動的メモリ領域の解放
引数: void *ptr: malloc() や calloc() で確保した領域のポインタ
戻り値: なし
*/
/*
動的メモリを malloc() で確保し, そのアドレスを確認してみる.
そのあと, free() で領域を確保し, もう一度アドレスを確認してみる.
*/
/*
つまり, free() を実行しても, 確保した領域は解放されるが, アドレス
は NULL になっているわけではないということだ.
free() の後には mbuf = NULL 手動で入れる場合もあり得る.
*/
#include <stdio.h>
#include <stdlib.h> /* free */
int main(void){
char *mbuf = NULL;
int sz;
sz = 20 * sizeof(char);
mbuf = (char *)malloc(sz);
if(mbuf == NULL){
printf("メモリ確保に失敗した\n");
return -1;
}
printf("%p\n", mbuf);
free(mbuf);
printf("%p\n", mbuf);
return 0;
}
|
free.c の実行結果は:
[cactus:~/code_c/refer]% ./free
0x100100080
0x100100080