- ベストアンサー
文字列を格納する配列を、動的なメモリ確保で処理したい
文字数が一定でない文字列の一覧を、配列に格納したいと思っています。 "AAA" "BBBBB" "CC" このような文字列を配列に格納するのに普通にやるなら char test[3][24]; for(i=0;i<3;i++){ strcpy(test[i],file[i]); } (便宜上、file[0]には、"AAA",file[1]には"BBBBB"が格納されてるとします) こうやると、test[3][24]の24バイトとか余計に確保した分が無駄になるので、 必要な文字列の長さだけ配列を確保したいと考えています。 で、 char *test[3]; for(i=0;i<3;i++){ //sizeには、各文字列のサイズが格納してあります。ここではその部分省略しますが test[i]= (char*)malloc(size); strcpy(test[i],file[i]); } とやれば (イメージで) test[0]= "AAA" test[1]= "BBBBB" test[2]= "CC" となると思ったのですが、うまく処理されませんでした。 このような処理をさせたい場合根本的に違うのでしょうか。 わかりにくい説明ですが、どなたかご存知の方よろしくお願いします
- みんなの回答 (10)
- 専門家の回答
質問者が選んだベストアンサー
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { const char *file[] = { "AAA", "BBBBB", "CC" }; char *test[3] = {0}; size_t i, length; for(i = 0; i < 3; ++i){ length = 1 + strlen(file[i]); test[i] = malloc(1 + length); if( test[i] == NULL){ break; }else{ strcpy(test[i], file[i]); } } for(i = 0; i < 3; ++i){ printf("<%d>: test=[%s]\tfile=[%s]\n", i, test[i], file[i]); if( test[i] ){ free( test[i] ); test[i] = NULL; } } } -----実行結果----- <0>: test=[AAA] file=[AAA] <1>: test=[BBBBB] file=[BBBBB] <2>: test=[CC] file=[CC] ----- 正しく処理されましたが…。 Windows2000sp4/VC++6.0sp6/ConsoleApp ※投稿するとインデントがつぶされるので2バイトスペースでインデントしています。
その他の回答 (9)
- JaritenCat
- ベストアンサー率37% (122/322)
文字コードは何でしょうか? もしUnicodeだったら半角文字の上位バイトが00になるので通常のstrlenは使えませんね。
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
ところで、 全角文字って SHIFT-JISでしょうね?
お礼
ご返答ありがとうございます。 皆さんから頂いた内容を元にコードを再確認して 不具合が直りました。 おっしゃる通り、プログラムの流れ自体は問題ありませんでした。 (事情がありましたが、質問内容と実際のコードの違いにより 不具合点がありました) どうもありがとうございました。
- apricotgx
- ベストアンサー率22% (20/88)
まず問題を特定した方がよいかもしれません。 どのようなデータの時にどういう問題が発生するのか 調べるのが先かと思います。 例えば ・コピー元のデータが1バイトデータ(全角日本語でない場合)で同様に問題が発生しますか? ・malloc時のサイズは適切ですか? ・サイズ分のコピーはされましたか? また > 今はi=1の時のstrcpy時にtest[0]="AAB"になってしまっている事です。 本当でしょうか? test[0]="AABBBBB"ではないですか? 質問内容のコードが実際のコードと合っていますか? (これが違うといつになっても適切な回答は得られないと思います)
お礼
ご返答ありがとうございます。 皆さんから頂いた内容を元にコードを再確認して 不具合が直りました。 おっしゃる通り、プログラムの流れ自体は問題ありませんでした。 (事情がありましたが、質問内容と実際のコードの違いにより 不具合点がありました) どうもありがとうございました。
- apricotgx
- ベストアンサー率22% (20/88)
> i=1処理時にi=20000とかになってしまいデータが壊れてしまったような感じです。 iのデータが壊れたタイミングの実行コードを 教えていただければ分かるかもしれません。
お礼
ご回答ありがとうございます。 #2の方へ回答しましたが、 i=20000の部分はまったく別の所の自分のミスでした。 これは今は問題ありません。 今はi=1の時のstrcpy時にtest[0]="AAB"になってしまっている事です。 何か思い当たる部分等ございますでしょうか?
補足
すみません。i=1の時のstrcpy時におかしくなる、 と書きましたが、 よく調べた所、malloc時にすでにtest[0]="AA○" となって、一番後ろの文字が消えてしまっていました。 どうぞよろしくです。
うそいいました。すみません。 大きさ3の配列に対するポインタは char (*test)[3] でした。トホホ
- JaritenCat
- ベストアンサー率37% (122/322)
問題なさそうですが、mallocの返値はNULLではない(正常に領域各できている)のですよね? 可能性としては、sizeが間違っているか?? 何回かバグ付きのmallocを実行させてメモリがぐちゃぐちゃになっていたとか・・・(OS再起動) ちなみに、mallocが確保するメモリサイズは処理系依存ですので、malloc(3)とやっても3以上が確保されるのは保証されますが、管理用領域とかキリのいい数字でもっとたくさんメモリ消費される可能性はあります。。。。
お礼
ご返答ありがとうございます。 皆さんから頂いた内容を元にコードを再確認して 不具合が直りました。 おっしゃる通り、プログラムの流れ自体は問題ありませんでした。 (事情がありましたが、質問内容と実際のコードの違いにより 不具合点がありました) どうもありがとうございました。
char *test[3] これでは大きさ3の配列に対するポインタですよ。 だから、 test[1]= "BBBBB" はダメなのではないかと思います。
お礼
ご返答ありがとうございます。 皆さんから頂いた内容を元にコードを再確認して 不具合が直りました。 おっしゃる通り、プログラムの流れ自体は問題ありませんでした。 (事情がありましたが、質問内容と実際のコードの違いにより 不具合点がありました) どうもありがとうございました。
- txrx
- ベストアンサー率45% (83/184)
No.1の方と同じく、問題ないと思います。 別の場所に問題があるのでは?
補足
ご返答ありがとうございます。 #1の方に回答した後、自分でもやりなおしていると 一箇所自分のミスがありまして それがi=20000の原因になっていました。 ただ、その部分を直した所、まだ処理自体はうまく動作していません。 うまくいかないのは、処理をすると i= 0の時 test[0]="AAA"になるのですが、 i= 1の時 test[0]="AAB"となり test[1]="BBBB"となってしまって、 1文字変な所で削れてしまっているようです。 なにか思い当たる部分等ございますでしょうか?
- apricotgx
- ベストアンサー率22% (20/88)
一見問題なさそうに見えますが どのようにうまくいかなかったのでしょうか? 補足説明をお願いします。 ところでサイズにヌル分は含んでいますか?
補足
ご返答ありがとうございます。 サイズにNULLは含んでおります。 "AAA"であればサイズは3ですので (char *)MALLOC(3+1) としております。この認識でよろしかったでしょうか? うまくいかないのは、for文内のi=1の時にメモリが 吹っ飛んでいるような処理になっています。 i=1処理時にi=20000とかになってしまいデータが壊れてしまったような感じです。 i=0の時はtest[0]="AAA"にはなっているので そこまでは正しく処理されていいるような感じですが。。。 なにか思い当たる事はありますでしょうか? ちなみに、例では説明しやすいように"AAA"としてますが、 実際自分の処理は全角日本語でして "てすと" "もじれつ" というようになっています。 "てすと"であれば (char *)MALLOC(6+1)のようにメモリ確保していますが。。。
お礼
ご返答ありがとうございます。 実際に動くコードを教えていただきとても参考になりました。 このコードを元に再確認して相違点を直した所不具合が直りました。 おっしゃる通り、プログラムの流れ自体は問題ありませんでした。 (事情がありましたが、質問内容と実際のコードの違いにより 不具合点がありました) どうもありがとうございました。