第2回メモリ管理(4月21日)

今日のポイント

■ 文字列の入力やコピーの手段

strcpy, strncpyを使用するには、#include <string.h>が必要

■ メモリの動的割り当ての方法

割り当て後は、返り値が NULL でないことを確認しよう。NULL のときは割り当て失敗なので、使用不可。

不要になったら free で解放しよう。

■ ポインタ型変数の操作

■ 例題1

次のプログラムで、メモリ確保した領域を越えて、代入や参照をしている 個所を指摘しよう。
/* list0201.c */
#include <stdio.h>
#include <string.h>

int main() {
  char s1[5], s2[5], *s3;

  s3 = "abcde";
  strcpy( s1, s3 );
  strncpy( s2, s3, 5 );

  printf("s1 = %s\n", s1);
  printf("s2 = %s\n", s2);
  printf("s3 = %s\n", s3);

  return 0;
}

■ 課題1

次のプログラムは、動作はするが危険といえることが3つ、明かな誤りが 1つある。MAX - 1 文字の長さまでの文字列は、表示できるようにしたい。変 数 s1 はキーボードからの入力をいったん格納するために使い、変数 s2 は表 示するために使っているが、これらは変更せずに、修正せよ(prac0201.c)。 動作確認をして、自分なりに修正してみよう。その結果を TA か徳久に見せよ う。
/* list0202.c */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX 10

int main() {
  char *s1, *s2;

  s1 = (char *)malloc(sizeof(char) * MAX);
  fscanf( stdin, "%s", s1 );
  strcpy( s2, s1 );

  printf("==========\n");
  printf("%s\n", s2);
  printf("==========\n");

  return 0;
}

■ 課題2

ネームカード(構造体 NameCard)を 10 個用意し、キーボードから 10人の 名前を入力し、それを表示するプログラム(prac0202.c)を作れ。 max_name_length - 1 以上の長さの名前が入力されると、即、エラー終了する こと。include ファイルや変数宣言などの追加は自由である。主な追加個所に ? を書いているが、その他にも追加が必要かもしれない。
/* list0203.c */

typedef struct {
  char *name;
} NameCard;

int main() {
  int i, max_card, max_name_length;
  NameCard *cards;
  char *tmp;

  max_card = 10; // ネームカードの最大枚数
  max_name_length = 15; // 名前の文字列の格納サイズ( \0 を含む)

  tmp = ? 文字列の領域を max_name_length だけ確保

  cards = ? NameCard を max_card 個ぶんのメモリを確保;
  ? メモリ確保後の処理;

  for( i = 0; i < 10; i += 1 ) {
    ? cards の i 番目の name に文字列の領域を確保;
  }

  for( i = 0; i < 10; i += 1 ){
    ? キーボードから名前を入力し、tmp に入れる。;
    ? tmp を加工などをする;
    ?
    ? cards の i 番目の name に文字列をコピー;
  }

  for( i = 0; i < 10; i += 1 ){
    printf("%d: %s\n", i, cards[i].name);
  }

  return 0;
}

□ 宿題(小レポート)

次回の演習開始時に集めます。


(c) Masato TOKUHISA (2006, April, 17.)