
No.847223 reallocについて
No.847300 ポインタについて
と質問させてもらい、御回答をいただき、理解した(つもりな)のですが、以下のことが実現できなくこまっております。
(以前の質問はこれを実現するために質問しました。)
まず配列array[1][20]を用意します(つまり文字列最高20字格納できる要素数1個の配列を用意)。
そして動的にこの配列のサイズを変更して、なにか文字列を入力する毎に、代入するスペースを逐次確保したいわけです。(メモリが溢れない限りスペースを確保しまくる)
そこでcallocやreallocの記述の仕方に困っています。
まず、callocについて
char array[1][20];
char *pn, *pn2;
pn = (char *)calloc(sizeof(array)/sizeof(char),sizeof(char));
このボイドポインタをキャストする部分にchar* と
char** のどちらを使えばいいか、です。
そしてreallocについて、
if( (pn2 = (char *)realloc(pn, sizeof(array)*cnt)) == NULL ){
printf("メモリの確保失敗!\n");
exit(0);
}
pn=pn2;
strcpy(pn[cnt],input);
【ただし、cntは毎回1づつ増加する。】
【inputはchar型の配列で、なんらかの文字列がはいっている。】
としているのですが、これもキャストの仕方がわかりませんし、strcpyで、セグメンテーションフォルトになります。構造体を使ったリスト形式も考えたのですが、reallocの使いかたを覚えたいのであえてこの形式で実現しようとしています。
結局どうしたいかというと、realloc部をforループさせて、cntを1ずつ増加させ、
pn[1][20]
つぎは
pn[2][20]
つぎは
pn[3][20]
とどんどん増やしていきたいわけデス。
すこしわかりにくい説明だとおもいますが、不明点や、言い回しがオカシイ箇所があればご指摘下さい。
No.3ベストアンサー
- 回答日時:
おっしゃるとおり、第一引数がNULLの場合の動作はmallocです。
typedefをしない場合は、それぞれ
char (*pn)[20] = NULL;
と
pn = (char(*)[20])realloc(pn, sizeof(char[20])*cnt);
となるのかな。ちと自信ないですが。
再び御回答ありがとうございました。
(char(*)[20])
という風にキャストするんですね...
(char [20] *)とやっていたのでエラーにひっかかって困ってました^^;
char (*pn)[20]
とは、「char型の要素数20個の配列へのポインタ」を宣言しているわけですよね?
なんとなくわかってきました!
#1の方にアドバイスしていただいた方法での解決方法もきになるのでそちらのほうもがんばってみます。
No.4
- 回答日時:
『「20字格納できる配列」を指すポインタの配列』を増やすので。
char **array=NULL;
int i;
int n =5;
for (i=0; i<n; i++) {
array = (char**)realloc(array, sizeof(char*) * (i+1));
array[i] = (char *)calloc(20,1);
}
これで
char array[5][20];
であるかのように使える。
やはりこの方法だと多次元配列のように、array[0],array[1]の表すポインタが等間隔(20バイト)にならぶようなメモリ配置はできないんですね^^;最初は24バイト間隔になっていました。
mihano様の方法だと、
reallocでchar型ポインタの配列、array[0],array[1]と逐次確保していき、あたらしく割り当てられたarray[i]に、callocによって動的確保したchar型の要素数20個の配列の先頭アドレスをセットする。
こういう解釈でよろしいでしょうか。よろしければこの確認だけお願いします。
ところでこの方法でも、array[5][1]というアクセスができるのは驚ろきました。array[][]と記述は多次元配列しかできないとおもっていたのですが、(array[5])[1] という風に考えるとなっとくできました。
No.2
- 回答日時:
まず、arrayがサイズの決定にしか使われていないようなので
typedef char ARRAY[20];
などするべきです。その上で、pnの型は
ARRAY* pn = NULL;
です。reallocでの確保は、
pn = (ARRAY*)realloc(pn, sizeof(ARRAY)*cnt);
となります。pn1は必要ありませんし、mallocやcallocも使う必要はありません。
nyan5504様の方法でとりあえずできました。ありがとうございます。
「C言語 関数の使いかた+作り方 完全制覇」という書籍をまた改めて確認したところ、pn部分には「NULLを指定してもよい」とかいてありました^^;また見落していました、すいません。。。 NULLを指定したときの動作はMALLOCと同じと考えてよろしいでしょうか?
ひとつだけ疑問なのですが、もしこれにtypedefを用いなければどうかけるのでしょう。。
頭が混乱して疑問ばかりが生じてしまって申し訳ないです。
No.1
- 回答日時:
char array[1][20];
このような静的配列のサイズを変更することはできません。
逆に言えば、動的に確保すればreallocを使えるわけです。
char **array=(char**)malloc(sizeof(char*));
array[0] = (char *)calloc(20,1);
足りなくなったらarrayをreallocで確保しなおしていく。
キャストの仕方がわからないのは、確保したものが何で、何に使おうとしているのか分かっていないということでしょう。
>char **array=(char**)malloc(sizeof(char*));
>array[0] = (char *)calloc(20,1);
これを元にreallocを考えたのですが、どうしても思い付きませんでした。
array = (char **)realloc(20*cnt);
でしょうか?これだけではたとえばcnt=2のとき、array[1]の値はNULLだったので、array[1]=array[0]+20;としなくてはいけませんでした。さらにarray[1][0]という記述ができなかったので、たぶんこれもだめですよね。
array[1]=(char *)realloc(20*cnt);
ともやってみましたが、これは自分でもちがうのはわかります。
array[0]=(char *)realloc(20*cnt);
これもたぶんだめですよね。
mihano様の記述方法だと、どうreallocをつかって確保すればいいのでしょうか....
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- 数学 確率の最大値を求める方法について 確率 Pn<P(n+1)⇄Pn/P(n+1)<1のときと Pn>P 2 2022/07/29 20:15
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- 数学 A君とB君はコインを1枚ずつ投げ、2枚とも表、あるいは2枚とも裏が出れば、投げた2枚をA君がもらい、 3 2023/02/05 12:19
- 数学 環論の素元について 6 2022/05/09 04:04
- C言語・C++・C# const char** p;のとき、free(p)でC4090エラーとなるのはなぜですか 3 2023/03/31 16:28
- C言語・C++・C# c言語の問題です 課題1 (二分探索木とセット) 大きさ size の配列 array を考える。す 2 2023/01/10 21:08
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
CStringからchar*への型変換に...
-
C言語のintとcharの違いってな...
-
動的に配列を確保した時の操作...
-
strtok
-
文字列配列を動的に割り当てる...
-
C言語でポインターで詰まってい...
-
簡易版smtpクライアント(メール...
-
ファイル読込時に構造体の文字...
-
可変長構造体をファイルから読...
-
C言語での質問です。
-
カンマで区切った文字の抽出に...
-
ポインタ
-
教えて下さい。
-
ポインタについての質問です。
-
配列の動的確保
-
配列を返す
-
c言語でポインタ変数を用いた配...
-
ポインタを使って回文かどうか...
-
C言語 strstrの実装
-
C言語にて構造体のメンバがNULL...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
CStringからchar*への型変換に...
-
char*を初期化したいのですが
-
C言語のintとcharの違いってな...
-
char型にint型の数値を代入する。
-
C言語にて構造体のメンバがNULL...
-
fgetc( )の戻り値はなぜ整数??
-
char 文字列型 の表現範囲が-12...
-
fstream型オブジェクトを関数の...
-
C++17で、unsigned char * 配列...
-
DWORDとcharの変換
-
文字列内の数字削除
-
new charとnew char[N]の違いは?
-
文字型配列に格納した空白の切捨て
-
C++Builder 2009 テキスト...
-
csvファイルをfscanfで読み込む...
-
文字列の途中から途中までを抽出
-
[C] 構造体メンバーのカンマ区...
-
エクセルのMID関数は、C言語では?
-
小数点入りの文字列をfloat型に...
-
wsprintf( ポインタ , "%d" , "...
おすすめ情報