• ベストアンサー

reallocでうまくメモリを拡張出来ていない?気がしますが・・・

S117の回答

  • ベストアンサー
  • S117
  • ベストアンサー率40% (18/45)
回答No.8

とりあえず理解を助けるためにアドバイス。 ポインタとは、 「"値"が格納された場所を示すための"値"」 です。 これは、ポインタが場所を示すものであるということのほかに、ポインタ自身が値に過ぎないことを示します。すなわち、ポインタがポインタを指すことができます。 int func(int a*) { *a = 10; } int main(void) { int a = 0; func(&a); printf("%d", a); //10 } このコードは読めますよね? 重要なのは、書き換えたい変数の型と、関数に渡す型の関係です。 int型の変数を書き換えたいのでint*型の値を渡しています。 一般化すれば、 「T型の変数を呼び出し先の関数で書き換えたいとき、渡すべき値はT*型となる。」 ということになります。 そして今回はTがstat*なので、渡すべき型はstat**なのです。 どういうポインタを使えばいいのか悩む必要はありません。型をみればすぐにわかります。

phenom
質問者

お礼

こちらで質問してから何度か挫折しそうになりましたが みなさんのおかげで解決することが出来ました。 ありがとうございました。 これからも質問することがあると思うのでまたよろしくお願いします。 (ここに出来上がったソースを貼り付けようとしたんですが、文字数が多い!と怒られました。)

phenom
質問者

補足

ありがとうございます。 >int func(int a*) { >*a = 10; >} >int main(void) { >int a = 0; >func(&a); >printf("%d", a); //10 >} >このコードは読めますよね? 大体分かるんですがint func(int a*)が分かりません。 a*というやり方は初めて見ました。それとなぜvoidでなくintなのかも 分かりません・・・。 >重要なのは、書き換えたい変数の型と、関数に渡す型の関係です。 >int型の変数を書き換えたいのでint*型の値を渡しています。 >一般化すれば、 >「T型の変数を呼び出し先の関数で書き換えたいとき、渡すべき値はT*型となる。」 >ということになります。 >そして今回はTがstat*なので、渡すべき型はstat**なのです。 >どういうポインタを使えばいいのか悩む必要はありません。型をみればすぐにわかります。 すごく分かりやすく説明してくれていて大変参考になりました。 ありがとうございます。

関連するQ&A

  • 配列の和を求めるプログラム

    キーから入力したデータを配列に入力した後、その和を求めるプログラムを作成したいのですが、プログラミング初心者の私にはさっぱりわかりません。 和を求めたいのに平均値が出てきてしまいます。 どこが間違っているのか教えてください。 #include <stdio.h> float data[5]; float total(int max); void main(void) { int cnt = 0; float d; printf("please input a data: "); scanf("%f", &d); while((cnt < 5) && (d > 0.0)) { data[cnt] = d; cnt++; printf("please input a data: "); scanf("%f", &d); } printf("total data: %5.2f\n", total(cnt)); } float total(int max) { int i; float total = 0.0; for(i = 0; i < max; i++) { total += data[i]; } return total / max; }

  • reallocとstrtokの併用について

    fscanfで文字列を読み込み、strtokでカンマ区切りにするという関数を作りたいのですが、 reallocすると先頭から徐々にデータが文字化けしていきます。 まず最初に4つ分のchar*を取ります。 もし、5つ目が見つかったらさらに4つ増やし、9つ目が見つかったらさらに。。。というようになっております。 n個目の判定はcntがn-1で真になり、reallocが成功したら個数を増やすようになってます。 5つ目が見つかった時点では出力に問題は無いのですが、6個目から侵食が始まっていきます。 原因がどうしても自分では分からなかったので、誰かお願い致します。 words.txtの内容(末尾改行なし) iii,jjj,kkkkkkkkk,l,m,n,ooooo,pppppppp,a,s,d,f,g main.c #include<stdio.h> #include<stdlib.h> #include<string.h> #include"C:\borland\bcc55\Include\malloc.h" int readlinefile(FILE *fp,char **words){ int cnt=0,len; char *line=(char *)malloc(256); char *tmp; if(line==NULL) return 0; if(fscanf(fp,"%s",line)!=EOF){ if((tmp=(char *)realloc(line,sizeof(char)*(strlen(line)+1)))==NULL){//できるだけメモリを節約してみる return 0; }else{ line=tmp; } len=strlen(line); printf("line:%d:%d:%s\n",len,_msize(line),line); if(len>1){//ファイル終端の改行を排除 int i; char *tok=strtok(line,",");//カンマで区切ったアドレスを得る while(tok){ if(cnt==0)printf("tok:1st:%x\n",tok); if(cnt>3&&cnt%4==0){//サイズが足りなくなった時 char **tmp2; if((tmp2=(char **)realloc(words,sizeof(char *)*(4+4*(cnt%4))))==NULL){ printf("words realloc ERROR\n"); break; }else{ printf("realloc\n"); words=tmp2;//reallocを適用 } } words[cnt]=tok; if(cnt){ printf("line(func)"); for(i=0;i<len+1;i++){ printf("%c",words[0][i]); } printf("\n"); } tok=strtok(NULL,","); printf("words[%d]:%x:%s\n",cnt,words[cnt],words[cnt]); printf("\n"); printf("tok:%d回目:%x\n",cnt+1,tok); cnt++; } return cnt;//正常終了した }else{ free(line); } } return 0; } int main(){ FILE *fp=fopen("words.txt","r"); if(fp){ int cnt=1; while(cnt){ int i; char **words=(char **)malloc(sizeof(char *)*4); words[0]=NULL; cnt=readlinefile(fp,words); printf("mainに戻りました\n"); if(cnt) printf("words:%d\n",cnt); for(i=0;i<cnt;i++){ printf("words[%d]:%x:%s\n",i,words[i],words[i]); } free(words[0]); words[0]=NULL; printf("\n"); free(words); } }else{ printf("file open ERROR\n"); } return 0; } 実行結果 なぜかコピペできないので実行するか斧でダウンロードお願いします。 http://www1.axfc.net/u/3352789.txt 全てまとめたもの http://www1.axfc.net/u/3352796.zip

  • C言語

    はじめまして。 C言語を学習しております。 参考書の練習問題19(下記)で以下の部分がどうしても理解できません。 1、【(People*)mallock】の部分で、mallockの前のPeopleを()でくくる意味とPeopleの後に*を付ける意 味がわかりません。 2、InputPeople関数とShowPeople関数の最後の部分(●の印をしている部分)になぜretutn 0がいらないのでしょうか(原文にはretutn 0の記述がありません)。 3、【while (1)】の部分で、while文の使い方は、「while(条件式){ 繰り返す文;}」のはずですが、なぜ条件式の部分が1なのでしょうか(a > bなどの形ではないのでしょうか)。 4、【while (1)】の部分で、InputPeople関数の引数としてdata[count]がありますが、何を意味しているのかがわかりません。People型の変数dataとint型の変数countを組み合わせてどういう意味合いになるのでしょうか。dataとcountはどういう関係でしょうか。 5、【while (1)】の部分で、count++する意味がわかりません。 6、【while (1)】文内の下記の記述が何を意味しているのかがわかりません。       if (count >= datasize) {       datasize += 10;       data = (People*)realloc(data,sizeof(People) * datasize);      } ここでつまづいて先に進めず困っております。 どうか教えていただきたく、お願い致します。 ●練習問題19 練習問題16(一番下に参考として解答を載せています)の、 「3人分の、名前、年齢、性別、を入力して表示するプログラムを作りなさい。 ただし、データは構造体で記憶することとし、 また、データの入力と表示はそれぞれ専用の関数を作って行うこととする。」 という問題を元に、何人分でも入力できるように改造しなさい。 なお、年齢に-1が入力されれば入力終了とする。 ※配列番号がint型なのでint型の最大値まで扱えれば良い。 ●練習問題19の解答 #include <stdio.h> #include <string.h> #include <stdlib.h> typedef struct { char name[256]; int age; int sex; } People; void InputPeople(People *data); void ShowPeople(People data); int main(void) { int i,count,datasize; People *data; datasize = 10; data = (People*)malloc(sizeof(People) * datasize); count = 0; while (1) { InputPeople(&data[count]); if (data[count].age == -1) break; count++; if (count >= datasize) { datasize += 10; data = (People*)realloc(data,sizeof(People) * datasize); } } for (i = 0;i < count;i++) { ShowPeople(data[i]); } free(data); return 0; } void InputPeople(People *data) { printf("名前:"); scanf("%s",data->name); printf("年齢:"); scanf("%d",&data->age); printf("性別(1-男性、2-女性):"); scanf("%d",&data->sex); printf("\n");     /*●retutn 0は不要?*/ } void ShowPeople(People data) { char sex[16]; printf("名前:%s\n",data.name); printf("年齢:%d\n",data.age); if (data.sex == 1) { strcpy(sex,"男性"); } else { strcpy(sex,"女性"); } printf("性別:%s\n",sex); printf("\n");     /*●retutn 0は不要?*/ } ●練習問題16の解答 #include <stdio.h> #include <string.h> typedef struct { char name[256]; int age; int sex; } People; void InputPeople(People *data); void ShowPeople(People data); int main(void) { People data[3]; int i; for (i = 0;i < 3;i++) { InputPeople(&data[i]); } for (i = 0;i < 3;i++) { ShowPeople(data[i]); } return 0; } void InputPeople(People *data) { printf("名前:"); scanf("%s",data->name); printf("年齢:"); scanf("%d",&data->age); printf("性別(1-男性、2-女性):"); scanf("%d",&data->sex); printf("\n"); } void ShowPeople(People data) { char sex[16]; printf("名前:%s\n",data.name); printf("年齢:%d\n",data.age); if (data.sex == 1) { strcpy(sex,"男性"); } else { strcpy(sex,"女性"); } printf("性別:%s\n",sex); printf("\n"); }

  • getchar()について 教えてください。

    visual studio 2010 professinalで以下のソースをデバッグして ”続行するには何かキーを押してください!”  で待機させたいのですが getchar()一個だけでは実現しません。   2個重ねるとOKです。どうしてでしょうか。  -------------- 以下のようにscanf関数がなければokということは突き止めたのですが、、、。  ご教授ください。 #include <stdio.h> int main(void) { int i; printf("なにか数字を入力してください。\n"); scanf("%d",&i); printf("今あなたが入力した数字は%dです。\n",i); printf("続行するには何かキーを押してください!"); getchar(); //getchar(); return 0; } ---------------------------------------------------------------- int main(void) { printf("続行するには何かキーを押してください!"); getchar();   return 0; }

  • ポインタエラー?

    コンパイルエラーで、つまづいてます 型が合ってないというのはわかるのですが どうしたらいいのかわかりません どこを改善すればいいでしょうか 問題とソースです↓ ソースは色々てを加えたので変なものが混じってます。 関数ichi()を作成し、プログラムを完成させよ。 main内部を変更してはならない。 (見つからない場合も考慮されている事に注意せよ。) #include <stdio.h> #define MAX 10 int *ichi(int *,int); int main() { int x[MAX], i, n, *p; for (i = 0; i < MAX; ++i) { scanf("%d", &x[i]); } scanf("%d", &n); p = ichi(x, n); if (p) { printf("%d ha %d ko me ni arimashita\n", n, p-x); } else { printf("%d ha arimasen desita\n", n); } return 0; } int *cnt; int * ichi(int *x,int n) { //int cnt; //cnt = 0; while(*x){ if(*x == n){ cnt = &n; //cnt = x; //return x; return cnt; } *x++; } return NULL; }

  • このプログラムの復元処理教えでください。助けてくだ

    #include <stdio.h> int main(void) { char a[51]; char b[101]; char c[51]; int i,k; int cnt; printf("文字例-->"); scanf("%s",a); i = 0; k = 0; while(a[i] !='\0') { cnt = 0; b[k] = a[i]; while(b[k] = a[i]) { cnt++; i++; } k++; b[k] = cnt + 48; k++; } b[k]='\0'; printf("b=%s\n",b); printf("c=%s\n",c); //-------------------------------------------------- getchar(); return 0; }

  • 下記のプログラムを実行したところ、不正な処理をしたので強制終了しましたとでました。何故でしょうか?

    #include <stdio.h> #include <stdlib.h> #include <float.h> int main( void ) { int val; int sum = 0; int max = -DBL_MAX; int cnt; char FileName[FILENAME_MAX]; FILE *fp; printf("入力ファイル名>>>"); scanf("%s", FileName ); if( (fp = fopen( FileName, "r" )) == NULL ) { printf("ファイルが見つかりません------%s\n",FileName ); exit( EXIT_FAILURE ); } for(cnt=0; ;cnt++) { fscanf(fp,"%d",&val); /*合計を求める*/ if(val == 0) { break; } sum += val; /*最大値を求める*/ if( max < val) { max = val; } } if( cnt > 0) { printf("平均は%g,最大値は%dです\n",(double)sum / cnt, max); } fclose( fp ); return EXIT_SUCCESS; } コンパイルはできるのですが実行すると このプログラムは不正な処理をしたので強制終了しますとでました 入力ファイル名>>>ってのも表示されません やはりこれは僕のパソコンがおかしいのでしょうか? 何か原因があるのなら教えてください

  • 素数判定の繰返し

    繰返し素数判定を行ない、CtrlーDで終了するプログラムをつくっています。 まず繰返しなしの素数判定プログラムを作り #include<stdio.h> int main(void) { int a,i; printf("自然数を入力:"); scanf("%d",&a); if(a<=0) printf("入力エラーです。\n"); else if(a==1) printf("1は素数ではない。\n"); else{ for(i=2; i*i<=a; i++){ if(a%i==0) break; } if(i*i>a) printf("%dは素数です。\n",a); else printf("%dは素数ではない。\n",a); } return(0); } これはちゃんとできたのですがそれを繰り返すことができません。 #include<stdio.h> int main(void) { int a,i; printf("自然数を入力:"); scanf("%d",&a); while((a=getchar())!=EOF){ if(a<=0) printf("入力エラーです。\n"); else if(a==1) printf("1は素数ではない。\n"); else{ for(i=2; i*i<=a; i++){ if(a%i==0) break; } if(i*i>a) printf("%dは素数です。\n",a); else printf("%dは素数ではない。\n",a); } printf("自然数を入力:"); scanf("%d",&a); } printf("プログラムを終了します。\n"); return(0); } これは訳わからないことになっちゃいます。。。 どうしたらいいんでしょうか??

  • このCのプログラムの修正と追加してくれませんか

    完成まで近いのですが、詰まっております このサイトでコンパイルなど出来ます http://ideone.com/ 以下の問題を解きました また問題文の指示には必ずしたがってください。また、この文章の条件でなく、人数が4人とかそれ以外の時でも出来るようなプログラムでお願いします。実行結果のとおりになるようお願いします http://i.imgur.com/nuzJv2v.png http://i.imgur.com/c7f3Vh2.png http://i.imgur.com/5aCqDO0.png http://i.imgur.com/9u8hHIM.png 問題は画像になっています、実行結果も含まれています #include<stdio.h> #include<string.h> /*構造体型struct Dataの宣言*/ struct Data{ char name[20]; int height; double weight; } data[100]; int cnt; int main(void) { int a; while(1) { printf("**************身長・体重の表示***************\n\n"); printf(" データファイルの読み込み・・・・・(1)\n"); printf(" 全てのデータを表示・・・・・・・・(2)\n"); printf(" 特定のデータを表示・・・・・・・・(3)\n"); printf(" 終わり・・・・・・・・・・・・・・(4)\n\n"); printf("処理番号を入力してください\n"); scanf("%d",&a); } if (a==1){ read_file(); } if (a==2){ p_all(); } if (a==3){} if(a==4){ break; } return a; } /*read_file関数の宣言*/ void read_file(void) { FILE *fp; char filename[20]; cnt=0; printf("読み込むファイルの名前を入力してください。\n"); scanf("%s",filename); fp=fopen(filename,"r"); if(fp==NULL){ printf("ファイルをオープンできませんでした。\n"); return 1; } while(fscanf(fp,"%c %d %lf",data[cnt].name,data[cnt].height,data[cnt].weight)!=EOF){ cnt++; fclose(fp); printf("ファイルを読み込みました。\n"); } return 0; } /*p_all関数の宣言*/ void p_all(void) { int i; printf("名前 身長(cm) 体重(kg)\n"); for(i=0;i<cnt;i++) { printf("%-2s %5d %.2f\n",data[i].name,data[i].height,data[i].weight); } } int main(void) { }

  • 数字文字をカウントするプログラムの動作について

    良い質問のタイトルが思い浮かばず、分かりづらいタイトルで申し訳ありません、C言語について質問させて頂きます。 C言語の参考書を買って夏休み中にプログラムの勉強をしているのですが、何故動作するのかがわからない例があります、ソースは以下の通りです。 #include <stdio.h> int main(void) { int i,ch; int cnt[10] = {0}; while(1) { ch = getchar(); if (ch==EOF) break; switch(ch) { case '0' : cnt[0]++;printf("%d\n",ch);break;/* printfは確認の為 */ case '1' : cnt[1]++;printf("%d\n",ch);break; case '2' : cnt[2]++;printf("%d\n",ch);break; case '3' : cnt[3]++;printf("%d\n",ch);break; case '4' : cnt[4]++;printf("%d\n",ch);break; case '5' : cnt[5]++;printf("%d\n",ch);break; case '6' : cnt[6]++;printf("%d\n",ch);break; case '7' : cnt[7]++;printf("%d\n",ch);break; case '8' : cnt[8]++;printf("%d\n",ch);break; case '9' : cnt[9]++;printf("%d\n",ch);break; } } puts("数字文字の出現回数"); for(i=0;i<10;i++) printf("'%d':%d\n",i,cnt[i]); getchar();getchar(); return(0); } といったプログラムです。 実行し、数値を入力、CTRL+Zで入力を終了し、出現回数を表示させる、という動作自体は無事にできるのですが、何故chの値が変更していくのかがわかりません、数値を入力した時点で51や49といったそれぞれ違う数値が表示されるのですが、chの値を変更させる命令を、何が引き起こしているのかが理解できません、3(51)と判定されて同じ数が無限にカウントされないのは何故なのでしょうか・・・・? また、その後の無限ループからの脱出をCTRL+Zがどうして引き起こすのかも理解できず困っています、教科書には「CTRL+Zは入力の終了を意味する」とあるのですが、これは一体どういう意味なのでしょうか、強制的に割り込んでEOFを代入するということなのでしょうか・・・? お時間がある時にでも、教えて頂けると助かります、よろしくお願いします。