No.15358![]() |
mallocとポインタについて 投稿者---kkk(2004/07/09 01:41:20) |
||
int load_pp_file(int **img, char*filename,int *width,int *height){ FILE *fp; fp=fopen(filename,"r"); *img=(int*)malloc((*width)*(*height)*3); とあって, img[x]=0x00ff & fgetc(fp); というようにしたのですが,BussError やSegmentation 違反になります. ポインタの使い方が間違っているのはわかるのですが これではだめなのでしょうか? |
No.15360![]() |
Re:mallocとポインタについて 投稿者---あかま(2004/07/09 02:41:29) |
||
>これではだめなのでしょうか? 何がしたいのか書かないと「だめ」の内容がわかりません。 コンパイルは通ればOKなだけなら「だめではない」でしょう。 実行時にエラーを出したくないのなら、セグメンテーションエラーがでるのですから「だめ」でしょう。 >ポインタの使い方が間違っているのはわかるのですが 使い方が間違っているのが分かるのなら直せばいいのですが。 2次元配列を動的に確保したいのなら過去ログを見てください。 違うのならやりたいことを書いてください。 |
No.15364![]() |
Re:mallocとポインタについて 投稿者---NykR(2004/07/09 08:56:45) |
||
何となく想像はつきますが、 >img[x]=0x00ff & fgetc(fp); xの値が(大体)どれくらいの時にSegmentation 違反やBussErrorになるかわかりますか? そこから原因は想像できませんか? |
No.15365![]() |
Re:mallocとポインタについて 投稿者---円零(2004/07/09 09:44:36) |
||
>>img[x]=0x00ff & fgetc(fp); > >xの値が(大体)どれくらいの時にSegmentation 違反やBussErrorになるかわかりますか? >そこから原因は想像できませんか? なるほど。的確なヒントですね。 まあ本でもヘルプでもインターネットでも、 ほかの人が書いたmallocの使い方をじーっと眺めれば気付くはず。 ところで三原色を格納したい場合、三次元配列の方が良さそうに思えますね。 |
No.15366![]() |
Re:mallocとポインタについて 投稿者---NykR(2004/07/09 09:48:15) |
||
>BussError BusErrorですね。Bussだとバスとは表記しなさそう。標準的な表記はブッスとかになりそうな気がする。 |
No.15369![]() |
Re:mallocとポインタについて 投稿者---ニタチ(2004/07/09 11:08:41) |
||
>int load_pp_file(int **img, char*filename,int *width,int *height){ >FILE *fp; > >fp=fopen(filename,"r"); >*img=(int*)malloc((*width)*(*height)*3); >img[x]=0x00ff & fgetc(fp); img[x]に格納できるのはint*型であって、int型ではありません。 *img、つまりimg[0]の指し示す先に代入しなければなりません。 |
No.15373![]() |
Re:mallocとポインタについて 投稿者---kkk(2004/07/09 12:55:25) |
||
int load_pp_file(int **img, char*filename,int *width,int *height){ FILE *fp; fp=fopen(filename,"r"); *img=(int*)malloc((*width)*(*height)*3); for(x=0;x<(*width)*(*height)*3;x++) * img[x]=( 0x00ff & fgetc(fp) ); あれから,かんがえて上のようにしたのですが まだエラーが出てしまいます. ポインタのポインタであるimgをどのように領域をとればいいのかが いまいちわかりません. *imgで領域をとって,imgのところでも個々に領域を確保するのかなあ ともおもうのですが. xの値がどのくらいまで 読み込まれているのわかりません. また,このforループの前に時点のmallocのところでエラーが でています. アドバイスをよろしくおねがいします |
No.15375![]() |
Re:mallocとポインタについて 投稿者---nop(2004/07/09 13:11:36) |
||
>*img=(int*)malloc((*width)*(*height)*3); img の型は? って言うか、あなたがやりたいのは、 img=(int*)malloc((*width)*(*height)*3); または img=(int**)malloc((*width)*(*height)*3); では? |
No.15376![]() |
Re:mallocとポインタについて 投稿者---NykR(2004/07/09 13:45:05) |
||
>xの値がどのくらいまで >読み込まれているのわかりません. 読み込んだときにprintfでxの値を表示させるとわかります。 # 実際にはfprintf(stderr, ...) # とか、デバッグ出力用のマクロを定義したり。 >また,このforループの前に時点のmallocのところでエラーが >でています. >アドバイスをよろしくおねがいします ではそのエラーメッセージをそのまま貼り付けてください。 # 間違ってもエラーの内容を、メッセージを貼り付けることなしに説明だけで済ませようとしないように。 # あなたは違うかも知れませんが、時々そういうことをする人がいるので念のため。 |
No.15379![]() |
Re:mallocとポインタについて 投稿者---kkk(2004/07/09 18:26:10) |
||
> >>また,このforループの前に時点のmallocのところでエラーが >>でています. >>アドバイスをよろしくおねがいします > >ではそのエラーメッセージをそのまま貼り付けてください。 ># 間違ってもエラーの内容を、メッセージを貼り付けることなしに説明だけで済ませようとしないように。 ># あなたは違うかも知れませんが、時々そういうことをする人がいるので念のため。 部分的に img =(int**)malloc((*width) * (*height) * 3); と (*img)[x] =( 0x00ff & fgetc(fp)); としたところ以下のエラーがでました P6 640,480 255 ERRORExit 1 となっています. mallocで領域を確保する前にppmファイルのMAGICと画像サイズ最大値を読み込んでいます. そして、次にppmファイルから値を入れる領域を作るところでエラーになっていると思います. 僕がやりたいのは,ppmファイルを読み込むことで, 他の人が書いたC++のプログラムをCに変える作業をしています. 元のC++では、 (*img)=new int[(*width)*(*height)*3]; となっていて, for(x=0;x<(*width)*(*height)*3;x++) (*img)[x]=0x00ff&fgetc(fp); となっています. この部分をCに直そうとして エラーがでてしまって. |
No.15380![]() |
Re:mallocとポインタについて 投稿者---ぽこ(2004/07/09 18:34:23) |
||
kkkさんが確保したメモリサイズと C++の元ソースで確保しているメモリサイズが違う気がしますが。。 kkkさんのソース > img =(int**)malloc((*width) * (*height) * 3); 元のC++ソース >(*img)=new int[(*width)*(*height)*3]; malloc(sizeof(int) * (*width) * (*height) * 3)では? |
No.15382![]() |
Re:mallocとポインタについて 投稿者---kkk(2004/07/09 18:38:06) |
||
ありがとうございます. しかし,その場合もいろいろと試したのですが だめでした. P6 551,477 255 Segmentation fault というエラーがでてしまって |
No.15381![]() |
Re:mallocとポインタについて 投稿者---kkk(2004/07/09 18:35:34) |
||
int load_ppm_file(int **img, char *filename, int *width, int *height) { FILE *fp; char magic[BUFSIZ]; int maxlevel, x; fp = fopen(filename, "r"); if (fp == NULL) return -1; fscanf(fp, "%s %d %d %d", magic,width,height,&maxlevel); printf("%s?n",magic); printf("%d,%d?n",*width,*height); printf("%d?n",maxlevel); if (strncmp(magic, "P6", 2)) { fprintf(stderr, "Error: %s is not raw ppm format!?n", filename); exit(1); } (*img) =(int**)malloc((*width) * (*height) * 3); if(*img==NULL){ printf("ERROR"); exit(1); } for (x = 0; x < (*width) * (*height) * 3; x++){ (*img)[x] =( 0x00ff & fgetc(fp)); } fclose(fp); free(*img); return 0; } すみません.ソースをのせさせていただきます. どうしてもエラーがでてしまって自分ではどうしようもないので. |
No.15383![]() |
Re:mallocとポインタについて 投稿者---ぽこ(2004/07/09 18:56:33) |
||
この関数を呼び出す時の第一引数に当てる変数は どのように定義されてますか? int main() { int **img;//この変数定義で load_ppm_file(img,(後は省略));//第一引数に持ってくるとNG } 上記のようなことやってませんか? |
No.15384![]() |
Re:mallocとポインタについて 投稿者---kkk(2004/07/09 19:08:44) |
||
><pre> この関数を呼び出す時の第一引数に当てる変数は どのように定義されてますか? int main() { int **img;//この変数定義で load_ppm_file(img,(後は省略));//第一引数に持ってくるとNG } 上記のようなことやってませんか? int *imin, *imout; load_ppm_file(&imin, imin_name, &width, &height); のようにして関数を読み出しているのでいいとおもうのですが いま (img) =(int**)malloc(sizeof(int*)*(*width) * (*height) * 3); if(img==NULL){ printf("ERROR"); exit(1); } for (x = 0; x < (*width) * (*height) * 3; x++){ (*img)[x] =( 0x00ff & fgetc(fp)); } としたら,forループまではとおったのですが forルーポの値を入れるところでSegmentation faultとなってしまいました |
No.15385![]() |
Re:mallocとポインタについて 投稿者---あかま(2004/07/09 19:44:17) |
||
一次元配列なの?多分みんな二次元だと思ってるような。 いや、それだとポインタのポインタのポインタが必要か。 とりあえず、一次元ならこうかな。 *img =(int*)malloc(sizeof(int)*(*width) * (*height) * 3); if(*img==NULL){ printf("ERROR"); exit(1); } for (x = 0; x < (*width) * (*height) * 3; x++){ (*img)[x] =( 0x00ff & fgetc(fp)); } heightとwidthをポインタで渡す必要はないよね。 あと関数の最後でfree(*img);してしまってるけどいいのでしょうか? 関数内限定ならimgを引数で渡す必要さえないのですが。 個人的には、確保した配列の先頭アドレスを返すようにすれば、 余計なポインタのポインタとか考えなくてすむので楽だと思います。 あとお約束の一言(重要) ソースを添付するときは「HTML変換ツール」を使ってください。 |
No.15386![]() |
Re:mallocとポインタについて 投稿者---ぽこ(2004/07/09 19:55:36) |
||
>(img) =(int**)malloc(sizeof(int*)*(*width) * (*height) * 3); > if(img==NULL){ > printf("ERROR"); > exit(1); > } > for (x = 0; x < (*width) * (*height) * 3; x++){ > (*img)[x] =( 0x00ff & fgetc(fp)); > } >としたら,forループまではとおったのですが >forルーポの値を入れるところでSegmentation faultとなってしまいました このソースコードでは本当にkkkさんが仰る所で セグメントフォールトが出てるか分かりません。 for文の前に次のコードを挿入してください。 printf("img = %p, *img=%p\n",img, *img); これが出力されますか? どんな出力になりますか? #(*img) = (int*)malloc(略);じゃないですか? |
No.15387![]() |
Re:mallocとポインタについて 投稿者---NykR(2004/07/09 19:59:52) |
||
>(img) =(int**)malloc(sizeof(int*)*(*width) * (*height) * 3); では、imgはポインタの配列の先頭要素へのポインタになりますが、この要素の値は不定です。 > (*img)[x] =( 0x00ff & fgetc(fp)); では、配列の先頭要素(*img)を参照していますが、不定の値は参照してはいけません。 少なくとも領域確保は、 *img = (int*)malloc(sizeof(int) * (*width) * (*height) * 3); の様にすべきでしょう。 というか中で解放するなら int load_ppm_file(int *img, const char *filename, int *width, int *height) { // ...snip img =(int*)malloc(sizeof(int) * (*width) * (*height) * 3); if(img==NULL){ printf("ERROR"); exit(1); } for (x = 0; x < (*width) * (*height) * 3; x++){ img[x] =( 0x00ff & fgetc(fp)); } fclose(fp); free(img); return 0; } でいいと思うんですが。 |
No.15388![]() |
Re:mallocとポインタについて 投稿者---kkk(2004/07/09 20:33:06) |
||
みなさんありがとうございます. 関数でppmファイルを取り込むのをやめて mainでながながと書くようにしたら ポインタのポインタもなくなり成功しました. まだ,関数の中でのポインタのポインタでの領域の確保がよく わかっていませんが,今回は成功したのでこれでいきたいと思っています. ありがとうございました. |
No.15377![]() |
Re:mallocとポインタについて 投稿者---ニタチ(2004/07/09 14:58:16) |
||
>int load_pp_file(int **img, char*filename,int *width,int *height){ >FILE *fp; >fp=fopen(filename,"r"); > >*img=(int*)malloc((*width)*(*height)*3); > >for(x=0;x<(*width)*(*height)*3;x++) > * img[x]=( 0x00ff & fgetc(fp) ); こうじゃない? (*img)[x]=( 0x00ff & fgetc(fp) ); |