動的なメモリの確保

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
にじいろもよう

動的なメモリの確保

#1

投稿記事 by にじいろもよう » 17年前

C言語について入門書を勉強した後、今はポインタについて勉強しています。
そして、動的な記憶域の確保を勉強し、
文字列の配列の動的な確保などは理解できるようになったのですが

個人的に疑問になったことがひとつあります。
「配列を使用せずにcalloc関数を用いて名前の入力・出力等は行えないのか??」
ということです。

例えば、「配列を使用せずに」
【calloc関数などを用いて確保した記憶域へ名前の入力を繰り返す】
または
【calloc関数を用いて、3文字まで・最大5人分入力し最後に出力できる】
というようなプログラムは可能でしょうか?

自分でも本や検索等で調べているのですが、わかりません。
疑問を解決したいと思っていますので、できれば助言等お願いします(><)

box

Re:動的なメモリの確保

#2

投稿記事 by box » 17年前

calloc関数は、引数で指定した分の領域を確保し、
中身を0x00で初期化する、という機能を持っています。
入力・出力の機能はありません。

calloc関数で確保した領域は、あたかも配列であるかのように扱えます。
配列の場合と同様に、当該の領域に入力したり
当該の領域の内容を出力したりできます。

たかぎ

Re:動的なメモリの確保

#3

投稿記事 by たかぎ » 17年前

calloc を使う場合でも、配列を全く使わずに実装するのは、難しいというより面倒ですね。
一応作ってみました。
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
  char *data = calloc(5, 3);
  if (data == NULL)
    return EXIT_FAILURE;

  char *cur = data;
  for (int i = 0; i < 5; i++)
  {
    int c;
    for (int j = 0; j < 3 + 1; j++)
    {
      c = getchar();
      if (c == EOF || c == '\n')
      {
        if (j == 0)
          goto print;
        break;
      }
      *cur++ = (char)c;
    }
  }

print:
  cur = data;
  for (int i = 0; i < 5; i++)
  {
    for (int j = 0; j < 3; j++)
    {
      int c = *cur++;
      putchar(c);
    }
    putchar('\n');
  }

  free(data);
  return EXIT_SUCCESS;
}
文字列定数も含めて、配列は全く使っていません。

にじいろもよう

Re:動的なメモリの確保

#4

投稿記事 by にじいろもよう » 17年前

『box ..神』さん返信ありがとうございます。

>calloc関数で確保した領域は、あたかも配列であるかのように扱えます。
>配列の場合と同様に、当該の領域に入力したり
>当該の領域の内容を出力したりできます。

「あたかも配列であるかのように・・・」という文章のお陰で
僕自身がcalloc関数に関して間違った理解をしていたことがわかりました(><)
そこで今、もう一度テキストを読み直し、プログラムを作成しています!!
作成して、また疑問が生じたらすぐに載せたいと思います。

にじいろもよう

Re:動的なメモリの確保

#5

投稿記事 by にじいろもよう » 17年前

『たかぎ』さんサンプルとなるソースありがとうございます。
参考にさせていただきました。

自分なり
「calloc関数でメモリを確保し、そこに名前を入力する。
 ただし、数字の7を入力すると、名前の入力も終了。そこまでの名前を出力する」
というプログラムを作成しようと試みました。

しかし、7を入力しても名前の入力は終了せず・・・(TT)
実行はされるもののそのあと「問題が発生したためstudy.exeを終了します。・・・」と出てしまいます。
以下にそのソースを示しますのでご指摘よろしくお願いします(><)

【ソース】
/**********************************************
* 入力された名前を出力するプログラム *
**********************************************/

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

int main(void)
{
char **p;
int num,i,no;

do{
printf("何人分入力しますか【1-10】:");
scanf("%d",&num);
if(num < 0 || num >10)
printf("1~10までを入力してください。\n");
}while(num < 0 || num >10);

p =(char **)calloc(num,sizeof(char *));

if(p==NULL)
printf("記憶域の確保に失敗\n");
else
{
no = 0;
for(i=0;i<num;i++){
p = (char *)calloc(1,sizeof(char));

if(p==NULL)
printf("記憶域の確保に失敗\n");
else{
printf("%d人目の名前:",i+1);
scanf("%s",p);
if((int)p == 7)
goto print;
no++;
}
}
}

print:
printf("\n");
printf("------出力------\n");
for(i=0;i<no;i++)
printf("%d人目の名前:%s\n",i+1,p);
free(p);

free(p);

return(0);
}
 

box

Re:動的なメモリの確保

#6

投稿記事 by box » 17年前

もともとのコードに何ヶ所か手を入れてみました。
ご自分のコードと見比べてみてください。
何か不明点があれば、質問してください。


/********************************************** 
* 入力された名前を出力するプログラム * 
**********************************************/ 

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

int main(void)
{
	char **p;
	int num, i, no;
	
	do {
		printf("何人分入力しますか【1-10】:");
		scanf("%d", &num);
		if (num < 1 || num > 10)
			printf("1~10までを入力してください。\n");
		else
			break;
	} while (1);
	
	p = (char **) calloc(num, sizeof(char *));
	if (p == NULL) {
		printf("記憶域の確保に失敗\n");
		exit(1);
	}
	else {
		no = 0;
		for (i = 0; i < num; i++) {
			p = (char *) calloc(80, sizeof(char));
			if (p == NULL) {
				printf("記憶域の確保に失敗\n");
				exit(1);
			}
			else {
				printf("%d人目の名前:", i + 1);
				scanf("%s", p);
				if (strcmp(p, "7") == 0)
					goto print;
				no++;
			}
		}
	}
	
	print:
	printf("\n");
	printf("------出力------\n");
	for (i = 0; i < no; i++) {
		printf("%d人目の名前:%s\n", i + 1, p);
		free(p);
	}
	free(p);
	return 0;
}

管理人

Re:動的なメモリの確保

#7

投稿記事 by 管理人 » 17年前

同じ投稿が2つあったようなので、片方消しておきました。
後、「神」や「入門者」などの表示は掲示板ランクでして、
過去にどれ位ここの掲示板で書き込みしたかを表すもので、名前ではありません。
ですので、「box ..神」さんではなく、「box」さんですので。

掲示板ランクについては掲示板上メニューの「昇進状態」をクリックすれば全員のランクが見れます。
別にどうでもいいこと事ですが・・。

にじいろもよう

Re:動的なメモリの確保

#8

投稿記事 by にじいろもよう » 17年前

boxさん返信ありがとうございました。
自分なりに調べて上に示して頂いたソースも理解でき無事にコンパイルできました。
本当にありがとうございました。

また、以前同じ投稿を2つ挙げてしまっていたので迷惑をおかけしてすみません。
マナーはしっかりと守りながらこの掲示板を活用させていただこうと思います。

閉鎖

“C言語何でも質問掲示板” へ戻る