C言語関係掲示板

過去ログ

No.195.サブルーチンでのアロケート


No.1235

サブルーチンでのアロケート
投稿者---shorokuroneko(2002/03/11 16:55:35)


皆さん、ご無沙汰しています。shirokuronekoです。

また皆さんのお力を、お借りしたくて投稿致しました。
説明が下手なので、プログラムを書きます。

void sabu(char *);

void main()
{
char *out;

sabu(out);

printf("out -> %s\n",out);

}

void sabu(char *in)
{
int ilen;
char moji[10];

memset(moji,'\0',10);
strcpy(moji,"message01");

ilen = strlen(moji);

in = (char *)malloc(sizeof(char) * ilen);




}

としたら、値の割り振られていないポインタが参照されたと警告メッセージが
表示されました。
子関数で、子関数の引数ポインタ変数をmallocさせることは可能なのでしょうか?
本来は可変長のサイズをmallocしたいので、値を割り振ることはできないと
思うのですが、なにか良い方法はありませんでしょうか。

よろしくお願い致します。

No.1236

Re:サブルーチンでのアロケート
投稿者---C職人(2002/03/11 19:06:47)


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

void getArea(char *,char *);

int main(void)
{
char *sp=NULL; /*はじめはどこも指していない状態にしておく(そうすれば警告は出ません)*/
char buf[256];

printf("文字列を入力してください。\n");
/*getsは最大読み込みバッファ長を超えて読み込んでしまうのでfgetsを使う*/
fgets(buf,256,stdin);

/*動的領域確保**/
getArea(sp,buf);

/*デバッグ用*/
printf("%s\n",buf);

/*メモリ開放*/
free(sp);

return 0;
}

void getArea(char *p,char *buf)
{
/*標準入力から入力した文字数分エリア確保*/
p=(char *)malloc(strlen(buf)+1);
if(p==NULL){
fprintf(stderr,"メモリの確保に失敗しました。\n");
exit(1);
}

}

上記のような感じでしょうか。



No.1237

Re:サブルーチンでのアロケート
投稿者---shorokuroneko(2002/03/11 19:23:55)


shirokuronekoです。ご返答ありがとうございます。
この方法でアロケートした変数をmainで使うことはできないのでしょうか?
できれば、教えて頂きたいのですが。
(もしかして、関数をchar *型にするのかな。)

お手数ですが、よろしくお願い致します。

No.1238

Re:サブルーチンでのアロケート
投稿者---C職人(2002/03/11 23:06:58)


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

/*プロトタイプ宣言*/
char *getArea(char *,char *);

int main(void)
{
char *p=NULL; /*はじめはどこも指していない状態にしておく(そうすれば警告は出ません)*/
char buf[256];

printf("文字列を入力してください。\n");
/*getsは最大読み込みバッファ長を超えて読み込んでしまうのでfgetsを使う*/
fgets(buf,256,stdin);

/*動的領域を確保し、先頭アドレスを取得*/
p=getArea(p,buf);

/*確保した領域に、入力した文字列をコピーする*/
strcpy(p,buf);

/*デバッグ用*/
printf("%s\n",p);

/*メモリ開放*/
free(p);

return 0;
}

char *getArea(char *p,char *buf)
{
/*標準入力から入力した文字数分エリア確保*/
p=(char *)malloc(strlen(buf)+1);
if(p==NULL){
fprintf(stderr,"メモリの確保に失敗しました。\n");
exit(1);
}
/*確保した領域の先頭アドレスを返す*/
return p;

}

上記のような感じでしょうか
char *で取得したアドレスを返してやりメイン側で受け取れば
使えますよね。
このやり方が最良かどうかはわかりませんが、どうでしょうか。
mallocは開発などではよく使うので知っておくと今後役に立つでしょう。



No.1239

Re:サブルーチンでのアロケート
投稿者---shirokuroneko(2002/03/12 02:18:56)


shirokuronekoです。C職人さん、ご返答ありがとうございます。
やはりchar *を戻り値として使用するということですね。
あと私のほうで考えたのが、ポインタ変数をグローバル化すれば、
いいのかな?なんて考えていました。
この考え方の場合、何か問題点はありますでしょうか?
私が思いつくところでは、プログラムのあらゆるところで使用できて
しまうため、メモリ系のバグを生みやすくなる程度しか思いつきません
でした。今後のために、何かございましたらご返答ください。

よろしくお願い致します。

No.1240

Re:サブルーチンでのアロケート
投稿者---かずま(2002/03/12 03:45:16)


> としたら、値の割り振られていないポインタが参照されたと警告メッセージが
> 表示されました。

初期化されていない out の値(不定) を sabu に渡しているのですから、
この警告メッセージは当然でしょう。

> 子関数で、子関数の引数ポインタ変数をmallocさせることは可能なのでしょうか?

質問の意味がよくわかりませんが、こんなことがしたいのでしょうか。

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

void sabu(char **);

int main()
{
  char *out;

  sabu(&out);
  printf("out -> %s\n", out);
  free(out);
  return 0;
}

void sabu(char **in)
{
  static char m[] = "message01";

  *in = malloc(sizeof m);
  strcpy(*in, m);
}


No.1243

Re:サブルーチンでのアロケート
投稿者---shorokuroneko(2002/03/12 19:21:11)


shirokuronekoです。
かずまさん、ご返答ありがとうございました。
私の説明に至らない点が御座いましたことを、
お詫び致します。

戻る


「初心者のためのポイント学習C言語」 Last modified:2002.05.14
Copyright(c) 2000-2002 TOMOJI All Rights Reserved