サイトマップ / C言語講座>出入り口>総目次>目次:ヒープ領域>メモリの割り付
[クイックソート]←このソース→[ヒープというデータ構造]
/* 今日は、文字列をヒープ領域に保存する関数を作ります。ANSI C には、このようなライブラリ関数はありませんが、たいがいの処理系で用意されています。それは、このようなものです。
#include <string.h> char *strdup(const char *s); 例:t = strdup(s); 実行結果 戻り値 複製した文字列へのポインタ
文字列は、例えば、下のように宣言します。
char str[7] = "string";
文字の数より配列の要素の数が1多いのは、Cでは文字列の末尾にNULL文字 ( '\0' ) が追加されるからです。[ ] の中の 7 は、省略可能です。コンパイラが代わりに数えてくれます。配列の名前 'str' は、この配列の先頭アドレスになります。文字列を複製する関数へは、このアドレスを渡します。
渡された関数は、文字列の長さがわかりません。そこで、標準ライブラリ関数、strlen( ) を使って、文字列の長さを求めます。strlen( ) は、次のように定義されています。
#include <string.h> size_t strlen(const char *s); 例:n = strlen(s); 実行結果 戻り値 成功 s の長さ
strlen( ) は文字列 s の長さを返します。末尾の '\0' は数えません。
size_t は、string.h の中で、
typedef unsigned size_t;
などと、型が宣言されています。文字列の長さがわかったら、文字列の長さ + 1 の char 型の配列 ( メモリブロック ) を用意します。 */
/* それには、標準ライブラリ関数 malloc( ) を使います。
malloc( ) は、実行時にヒープ領域に動的にメモリブロックを割り付けます。このブロックには、名前を付けることができません。そこで、ポインタを通してアクセスします。この理由で、malloc( ) は、注意深く使う関数です。malloc( ) を使っているルーチンにバグがあると、プログラム実行時に容易にクラッシュして、暴走します。
#include <stdlib.h> void *malloc(size_t size); 実行結果 戻り値 成功 割り付けられたメモリブロックへのポインタ 失敗 NULL
'void *' という記述が出てきました。'void *' は、ポインタを返すということです。しかし、特定の型のポインタではありません。下記のように使用します。
p = (char *)malloc(size); p: char 型ポインタ p = (short *)malloc(size); p: short 型ポインタ p = (long *)malloc(size); p: long 型ポインタ
ここまでを、C言語で記述すると、下記のようになります。
t = (char *)malloc(strlen(s) + 1);
t は char 型のポインタです。文字列の長さ + 1 のメモリを割り付け、その先頭アドレスが t に代入されます。
次いで、割り付けられたメモリブロックに、文字列をコピーします。コピーするには、strcpy( ) を使います。
#include <string.h> char *strcpy(char *s1, const char *s2); 例:strcpy(s1, s2); 実行結果 戻り値 成功 s1 へのポインタ
strcpy( ) は、文字列 *s2 ( 末尾の '\0' を含む ) をs1 へコピーします。これで、文字列が複製されたことになります。最後に、複製された文字列へのポインタを返して、この関数は完成です。
malloc( ) で割り付けられたメモリブロックは、不要になった時点、あるいは、プログラムの終わりに、解放しなければなりません。解放するには、標準ライブラリ関数 free( ) を使います。
#include <stdlib.h> void free(void *p); 例:free(p); 戻り値 なし
*/
#include <stdio.h> #include <stdlib.h> /* malloc( ) free( ) で必要 */ #include <string.h> /* strlen( ) strcpy( ) で必要 */ char *StringDup(const char *s); void main(void); /* 文字列をヒープ領域に保存する */ char *StringDup(const char *s) { char *t; /* malloc( ) で割り付けられたメモリブロックへのポインタ */ t = (char *)malloc(strlen(s) + 1); if (t == NULL) /* 失敗したら */ return (NULL); /* NULL を返す */ strcpy(t, s); return (t); /* 複製された文字列へのポインタを返す */ } void main(void) { char str[ ] = " Duplicate a string."; char *t; printf("オリジナル文字列: %s\n", str); /* 複製された文字列へのポインタを t に代入 */ t = StringDup(str); if (t != NULL) /* 成功したら */ /* 複製された文字列を表示 */ printf("複製された文字列: %s\n", t); else printf("メモリ不足!"); free(t); /* メモリを解放 */ } |
[クイックソート]←このソース→[ヒープというデータ構造]
/* (C) 2000- YFプロ. All Rights Reserved. */ 提供:C言語講座−それ自体コンパイルできる教材を使った講座です−