• 締切済み

fread関数および動的なメモリ確保について

こんにちは。 ファイルオープンし、fread関数にて1バイトずつ1024個をPktBuf配列へ格納し、sendto(winsock関数でUDPソケットの関数です)で1024Byteずつ送信しています。 #define DATA 1024 FILE *fp; char PktBuf[1024] fp = fopen(SEND_FILE_NAME,"rb+"); while((n = fread(PktBuf,1,DATA,fp)) != 0) {   sendto } fread(PktBuf,1,DATA,fp)の第2引数で、1と指定しているのですが・・・HPを参考にしているとsizeof(int)やsizeof(char)などが明記されている場合があるのですが、これは移植性を気にする場合に必要なことなのでしょうか? もし、第2引数のところを1から2へ変更した場合、2Byte×1024個=2048Byteとなり、配列[1024]に格納できないことを意味するのでしょうか? 最後に、fread関数およびmallocまたはcalloc関数を用いた、動的なメモリ確保について勉強しているのですが、記述方法がわからない状態です・・・現在の記述方法で問題はないのですが、動的なメモリ確保をすることが定説?と書かれていましたので、そちらも知りたいと思っています。 よろしくお願いします。

みんなの回答

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

freadの第2引数は読み込むバッファの形式にあわせるようにするのが一般的だと思います バッファを intでっとってあるならば sizeof(int) charでとっているのであれば sizeof(char) といった具合です freadはバッファへ読み込むデータを 第2引数で指定された項目を 第3引数で指定された個数分読み込むように設計されています ご質問のように fread( PktBuf, 2, DATA, fp ) といった具合に変更してしまうと PktBufが 1024バイトしか確保していないのに 2048バイト読み込んでもいいよといったことになり 1024バイト以降データは PktBufとは関係無い領域に書き込まれます となると 別の変数やスタックなどを破壊して 異常終了といった事態を招きます mallocやcallocなどは ポインタを返す関数ですので まず受け取るポインタ変数を宣言します callocは2つの引数をとります 項目数と項目のサイズです mallocは確保したい領域のサイズを引数とします 1024バイトのバッファなら // char型バッファ char *pBuf = NULL; pBuf = (char*)calloc(1024, sizeof(char)); pBuf = (char*)malloc(1024); // int型バッファ int *piBuf = NULL; piBuf = (int*)calloc(1024, sizeof(int)); piBuf = (int*)malloc(1024*sizeof(int)); 動的に確保した場合は free()を使って必ず開放するようにしましょう free(LPVOID)pBuf); free((LPVOID)piBuf); といった具合です #まず、お使いのCコンパイラのヘルプなどをお調べになることをお勧めします

bird0214
質問者

補足

返信ありがとうございます。 以下のように記述してみました。 #define SEND_DATA_SIZE 1024 int A_func{   //pBufを動的割り当て   char *pBuf=NULL;   pBuf = (char*)malloc(SEND_DATA_SIZE);   //fread関数にて   while((n = fread(pBuf, sizeof(char), SEND_DATA_SIZE, fp)) != 0) {    sendto   } } このように記述することで、動的なメモリ割り当てが行われているのでしょうか?

関連するQ&A

  • fread関数でわかりません。

    fread関数で次のようにソースを記述しました。 FILE *fp; char c[10]; int i; fp = fopen ("./aaa.txt", "rb"); fread(c, sizeof(char)-1, 10, fp); for(i = 0; i < 10; i++) printf("%02x ", *(c+i)); fclose(fp); return 0; aaa.txtの中には 0x1~0xAの10個の数字が記入されています。 cをint 型にすると正常に読み込めるのですが、char型だと 01 00 00 00 02 00 00 00 03 00 となってしまい、正常に読み込めません。 どうも、int型で読み込み、さらに引数 cにはchar *でキャストして渡しているように見受けられます。 Q1 どのようにしたら、char型で 10個一度に読み込めるようになるのでしょうか? Q2 int型(32bit)なら、一度に4文字読み込むと思いますが、何故一文字ずつ読み込むことになるのでしょうか? //getc で一文字ずつ読み込めば済む話ですが、気になり質問いたしました。

  • 「動的確保した2次元配列のメモリ解放」を関数化したい

    質問タイトルの通りですが、 「動的確保した2次元配列のメモリ解放」をC言語で関数化したいと思っています。しかし、関数の引数には動的確保した配列の先頭アドレスのみ渡す形にしたいです。そのような場合の関数化は可能ですか? どうもうまくいかず、困っています。 以下、具体的に、サンプルソースを記述します。 わかる方、よろしくお願いします。 //====================================================// #include<stdio.h> unsigned char** AllocByteArray2d(int column, int row); void FreeByteArray2d(unsigned char** box); int main(voidls){ unsigned char array**; array = AllocByteArray2d(2, 3); FreeByteArray2d(array); return 0; } unsigned char** AllocByteArray2d(int column, int row){ unsigned char* box; box = (unsigned char**)malloc( sizeof(unsigned char*)*column ) int i; for(i=0; i<column; i++){ box[i] = (unsigned char*)calloc( row, sizeof(unsigned char)); if(box[i] == NULL) exit(EXIT_FAILURE); } return box; } //引数では配列の先頭アドレスだけ渡す形にしたい void FreeByteArray2d(unsigned char** box){ //ここをどう書いたらいいかわからない }

  • 2次元配列の動的確保

    ある画像を読み込むため、その画像を格納できる幅、高さを持った配列を動的に確保しようと考えています。 幅をxsize、高さをysizeで次のように記述しました。 unsigned char **src; int i; src = (unsigned char**)malloc(sizeof(unsigned char*) * ysize); src[0] = (unsigned char*)malloc(sizeof(unsigned char) * xsize * ysize); for(i=1; i<ysize; i++) src[i] = (src[0] + i * xsize); わざわざポインタのポインタを使用したのは、動的に確保した配列を2次元的なアクセスをしたかったためです。 画像の読み込み時は fread(src[0], sizeof(unsigned char), xsize * ysize, fp); としています。 上に記述したソースは問題なく動作しました。 しかし、上の場合だと全ての配列を連続して確保することができません。つまりsrcでmallocを一回、src[0]でmallocを一回使っているため、ポインタの配列の直後に配列を確保する保障がありません。そこでいっぺんに確保することを考えました。 unsigned char **src; int i; src = (unsigned char **)malloc(sizeof(unsigned char *) * ysize + sizeof(unsigned char) * xsize * ysize); for(i=0; i<ysize; i++) src[i] = (unsigned char *)(src + sizeof(unsigned char *) * ysize + i * xsize); このように組み上げ、読み込み時は上のfreadと同様に記述したところエラーが出てしまいました。 やはり一行目のmallocで無理やりsizeof(unsigned char *) * ysize + sizeof(unsigned char) * xsize * ysize分確保するのは失敗だったのでしょうか?

  • 2次元配列への格納方法について

    こんにちは。 FILE *fp; SIZE 1024; int n; char Buf[1025]; while((n = fread(Buf,1,SIZE,fp)) != 0){ } というように、fread関数を用いて1024バイトずつ配列Bufへ格納しています。 以下に示すようなことを行う場合、どのように記述すればよいのでしょうか? B:バイナリデータ T:数値 TBBBBBBBBB・・・・・・B←1024バイト目 TBBBBBBBBB・・・・・・B ・ ・ ・ ・ TBBBBBBBBB・・・・・・B というように、配列内に格納したいと思っています。 Tは、テキストデータで1,2,3・・・・100という整数型を格納。Bは、バイナリデータでfread関数から取得したバイナリデータを格納します。 なぜ、Tを格納したいかといいますと、どのバイナリデータを指しているか?を判別するためです。 上記のようなことを行うためには、2次元配列を使用すればよいのでしょうか? 例:char Buffer[100][1025]

  • 配列の動的確保

    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] とどんどん増やしていきたいわけデス。 すこしわかりにくい説明だとおもいますが、不明点や、言い回しがオカシイ箇所があればご指摘下さい。

  • fread()エラー

    お世話になります。 今、バイナリファイルを操作しているのですが、 fread()でエラーになってしまいます。 char buf1[256]; FILE *fp; vector<string> f1; int num; fp = fopen("hoge.txt","r"); while( fgets( buf1, sizeof(buf1),fp ){ f1.push_back( buf1 ); num ++; } fclose(fp); FILE *cfp; unsigned char data[1024]; for(int i=0; i<num; i++ ){ cfp = fopen(f1[i].c_str(), "rb"); fread( data, sizeof(char), 1024, cfp ); } hoge.txtには、コンテンツ場所(パス)が複数記載されており、 その1つずつをfread()で読み込み解析したいのですが、 fread()でセグメンテーション違反になります。 f1の中味をprintf("%s",f1[0].c_str()); で見てみると正常にコンテンツの場所が格納されています。 また、 string pp = "/home/hoge/hoge.txt"; cfp = fopen(pp.c_str(), "rb"); fread(bb,sizeof(char),1024,cfp); とすると正常に動作します。 どうぞよろしくお願い致します。

  • reallocでメモリを再確保するには?

    こんにちわ, 今, 「すでに動的確保しているメモリをその型分1サイズだけ増やす」というプログラムを考えています。 具体的には, char* str_p; a=calloc(str_p, sizeof(char)); /*ここから問題のプログラム(実際はずっと動くので無理です*/ while(1) { a=realloc(str_p, sizeof(str_p)+sizeof(char)); } ・・・・・・ これだと,私的にはsizeof(str_p)で今のサイズを調べ,それにsizeof(char)を加えることで次々に1サイズ大きいメモリを再確保できると思ったのですが,ポインタのサイズを指していてそれにchar型のサイズをたしていていつも固定サイズになるみたいでうまくいきません。 どうすれば,char*などポインタ型の変数の大きさを調べられるのでしょうか。 また,どうすれば,1サイズずつ大きくできるのでしょうか。 よろしくおねがいします。

  • freadの最後

    100文字くらいのファイルのファイルポインタfpがあるとして、 char ch[200]; fread(ch,sizeof(char),sizeof(ch),fp) とした場合にchの中で、ファイルの最後っていうのを判断するにはどうすればいいですか?

  • 配列のメモリの確保

    先日メモリについてご質問させていただいたものですが、 今ファイルから読み込んだ文字列を配列に格納する作業を行なっています。 今は char buf[1000]; FILE fp; if((fp=fopen("○○.txt","r")) ==NULL){ printf("ファイルが開けません"); } while(fgets(buf,1000,fp) != NULL){ としてファイルを一行ずつ読み込んでその後単語ごとに配列に組み込みます このときファイルの文字列を格納する配列はbuf[1000]ですが このメモリでは足りないかもしれませんし多すぎるかもしれません。 足りない場合はエラーになるし多すぎる場合はメモリの無駄ですよね。 このような場合はメモリを取り直すべきなのでしょうか?その場合 どのような方法がありますか?調べてもint型の領域確保とかそういうのはあるんですがファイルから読み込んだ文字列の領域確保とかは見つからなかったので教えて下さい。

  • 画像を読み込む配列の確保。

    C言語について質問です。 画像を読み込む時、その画像の幅、高さを入力し、そのサイズに見合った配列を確保します。その後ファイル名を入力し、配列に読み込むプログラムを作成しました。 メインの部分のみ記述します。 int xsize, ysize, i; unsigned char **src; char filename[30]; FILE *fp; printf("ファイル名を入力してください:"); scanf("%s", filename); printf("画像の幅:");scanf("%d", &xsize); printf("画像の高さ:");scanf("%d", &ysize); src = (unsigned char **)malloc(sizeof(unsigned char *) * ysize); for(i=0; i<ysize; i++) src[i] = (unsigned char *)malloc(sizeof(unsigned char) * xsize); fp = fopen(filename, "rb"); fread(src[0], sizeof(unsigned char), xsize * ysize, fp); このように記述し、エラーもなく実行できたのですが、srcをこのまま出力すると変?な画像となって出力されてしまいました。 上のように記述した場合、矛盾する場所はあるでしょうか? そして、この方法以外に配列を確保する方法はあるでしょうか?

専門家に質問してみよう