• ベストアンサー

セグメンテーション違反とmalloc

char *name この宣言でプログラムの組初めはこれでいけたのですが char *name = (char *)malloc(sizeof(char) * 10); 後からこのようにmallocで動的メモリ確保しないとセグメンテーション違反が起きるようになりました。 なぜこうなるのでしょうか? それとmallocの使うタイミング(どういう時)に使えばよいのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.3

はなはだ失礼なことを申し上げますが、C言語の基本を理解されていないと思われます。 一般的に変数は、その内容にある値を設定してからでないと、その変数を使用することは、出来ません。これを変数の初期化と言います。 例えば int型の変数 aを確保したとして、これを初期化しないで使用するとどうなるかです。 int a; として if (a==10){ printf("aは10です\n"); }else{ printf("aは10ではありません\n"); } 上記のプログラムを実行するとぢうなるでしょうか。 答えは、「どうなるか判らない」です。 たまたま、「aは10です」が表示される場合もありますし、 たまたま、「aは10ではありません」が表示される場合もあります。 これは、int 型の変数aを確保したときに、その内容を初期化していないので、なにが入っているか判らない為にこの状態が発生します。 int型の変数を初期化せずに使った場合は、プログラムがどちらに転ぶか判らないだけですが、ポインター型の変数を値を初期化せずに使用した場合は、事情は異なってきます。 char *name;とした状態では、ポインターnameは初期化されていません。 従って例えば strcpy(name,"abc"); を実行したとすると、ポインターの示す先に、文字列"abc"をコピーします。 では、このポインターの示す先は、いったいどこなのでしょうか。 答えは、「初期化されていないので判らない」です。 とすると、たまたま、コピーしても安全なところを示している場合は、セグメンテーション違反は発生しません。 ところが、たまたま、コピーしてはならないアドレス(OSのみにアクセスが許されるアドレス、例えば0番等)を示していると、セグメンテーション違反になります。 >それとmallocの使うタイミング(どういう時)に使えばよいのでしょうか? メモリを必要とする時です。この意味が理解できるようになるためには、もう少し、ポインターについて、いろいろとプログラミングをして、ポインターになれることが必要です。

xaion0260
質問者

お礼

いろいろと説明を聞いてるうちに分かってきました。ありがとうございます。

その他の回答 (3)

  • don_go
  • ベストアンサー率31% (336/1059)
回答No.4

>それとmallocの使うタイミング(どういう時)に使えばよいのでしょうか? 使うタイミングもですが、使い終わった時の処理も重要 です。 malloc()等で動的に確保したメモリは使い終わった後は free()等で解放しておかないと、メモリリークを起こし メモリ不足によるプログラム異常の原因となります。 プログラムの他の部分を見ないと判りませんが、malloc() で動的にメモリを確保する必要があったのでしょうか? #エラーが起きるから対症療法的にmalloc()を使用した様に #思えます。 char name[10]; では駄目ですか?

  • buriburi3
  • ベストアンサー率44% (353/792)
回答No.2

以前動いていたのは偶然・たまたま・運が良かっただけです。 char *name だけでは領域も確保されていないし初期化もされていません。 何処にアクセスしているか全く分からない状態ですのでセグメンテーション・フォルトが起こって当然です。

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.1

> char *name > この宣言でプログラムの組初めはこれでいけたのですが このときに、nameにどうやってアクセスしていたかと、 > char *name = (char *)malloc(sizeof(char) * 10); > 後からこのようにmallocで動的メモリ確保しないとセグメンテーション違反が起きるようになりました。 このときに、nameにどうやってアクセスしているかを比べてみないことには、 何とも言えません。 可能でしたら、「前はこんなコードだった」と「今はこんなコードである」という 両方を見せてください。 前のコードはもう残っていないかもしれませんが…。

関連するQ&A

  • セグメンテーション違反

    OSはリナックスでC言語です。 #include<stdio.h> #include<stdlib.h> typedef struct{ int id; char *name; }user; int main(void) { user *users; int i,j; users=(user *)malloc(sizeof(user)*100); for(j=0;j<5;j++) scanf("%d",&(users+j)->id); scanf("%s",(users+j)->name); free(users); printf("input your id;"); scanf("%d",&i); printf("NO%d %s\n",(users+i)->id,(users+i)->name); return 0; } 上記のプログラムソースでセグメンテーション違反と出てしまいます。 原因はなんなのでしょうか。 教えていただければ光栄です。

  • セグメンテーション違反とは??

    linuxでC言語のプログラムを構築しています。 gccでコンパイルしたときにセグメンテーション違反という エラーが出てしまいます。 セグメンテーション違反とは一体なんの ことなんでしょうか? メモリのことだと思ってるんですが、原因がよくわかりません。C言語初心者なので わかりやすく教えて頂けるとありがたいです。

  • 「セグメンテーション違反」について

    参考書に載っていたプログラムを打ち込みながら勉強していたのですが、次のプログラムを動かしたときに「セグメンテーション違反」と出てきました。 /* 可変書式による印字_簡単な棒グラフ */ #include <stdio.h> main() { char *f, *a; int i; f="%2d = %-20.1s\n"; a="********************"; for(i=1; i<10; i++){ *(f+11)=i+'0'; printf(f,i,a); } } コンパイル後に、 「セグメンテーション違反です」 と、表示されて終わってしまいます。 何処が問題だったのでしょうか???教えて頂ければ幸いです。

  • mallocで動的確保後、値が変わる

    最近よく出くわすバグなのですが、mallocでメモリを動的確保して、いくつかの処理をした後に値が変わっていたり、読めなくてセグメンテーションエラーになることがあります。 根本的に何か間違っているのかもしれませんが、なかなかわかりません。 例えばこんな感じです ... int main(int argv,char *argc[]) { double *arrXn; double *arrFn; double *arrX; double *arrY; double *arrV; double *arrD; double **arrCn; ... //N(0~9)を受け取る arrXn=(double *)malloc(sizeof(double)*(N+1)); arrFn=(double *)malloc(sizeof(double)*(N+1)); arrX=(double *)malloc(sizeof(double)*(N+1)); arrY=(double *)malloc(sizeof(double)*(N+1)); arrV=(double *)malloc(sizeof(double)*(N+1)); arrD=(double *)malloc(sizeof(double)*(N+1)); arrCn=(double **)malloc(sizeof(double *)*(N+2)); for(incA=0;incA<=N;incA++){ arrCn[incA]=(double *)malloc(sizeof(double)*4); } for(incA=1;incA<N;incA++){ arrCn[incA][0]=arrFn[incA-1]; arrCn[incA][1]=arrV[incA-1]; arrCn[incA][2]=-3*arrFn[incA-1]+3*arrFn[incA]-2*arrV[incA-1]-arrV[incA]; arrCn[incA][3]=2+arrFn[incA-1]-2*arrFn[incA]+arrV[incA-1]+arrV[incA]; } printf("%lf",arrCn[1][1]);getchar(); //取れる for(incA=0;incA<=numHokan;incA++){ arrX[incA]=Setx(incA); //自作関数 } printf("%lf",arrCn[1][1]);getchar(); //セグメンテーションエラー 特に多次元配列を作成したり、動的確保を大目にすると起こりやすいです。 もし何かお気付きのことがありましたらよろしくお願いします。

  • mallocについて

    mallocについて 現在C言語でプログラムをかいているのですが、原因不明のエラーが出て困っています。 それはmallocによる動的メモリ確保を行ったとき、 (float *)malloc(sizeof(float)*200)の場合大丈夫ですが、 (float *)malloc(sizeof(float)*320)ではエラーが出てしまうのです。 しかし (float **)malloc(sizeof(float*)*640)とした場合エラーは出ませんでした。 これは何が原因でエラーが出ているのでしょうか? ちなみにコンパイルはできており、実行したとき プログラム名(7637) malloc: *** error for object 0x100ff7a08: incorrect checksum for freed object - object was probably modified after being freed. *** set a breakpoint in malloc_error_break to debug というエラーがでます。

  • セグメンテーション違反が出てしまいます・・・.

    #include<stdio.h> typedef struct tag{ int num; char name[10]; struct tag *next; }DATA; void add(void); DATA *head,*wp,*back; int main(void) { FILE *rfp,*wfp; char buf[256]; DATA *p; head=NULL; //ファイルを読み込み--------------------------- rfp=fopen("sample.txt", "r"); while(fgets(buf,256,rfp)!=NULL){ p=(DATA *)malloc(sizeof(DATA)); sscanf(buf,"%d %s", &(p->num),p->name); if(head==NULL){ head=p; head->next=NULL; back=p; } else{ back->next=p; back=p; } p->next=NULL; } fclose(rfp); //読み込み終了--------------------------------- } void add(void){ DATA *newp; newp=(DATA *)malloc(sizeof(DATA)); scanf("%d", &newp->num); scanf("%s", &newp->name); newp->next=NULL; for(wp=head; wp!=NULL; wp=wp->next){ if(head=NULL)head=newp; else if(newp->num < wp->num){ head->next = newp; } } } sample.txtからデータを読み込みそれを構造体のリスト構造にしてその構造体にデータを追加したいのですが、最後のhead->next=newpのところでセグメンテーション違反が出てしまいます。なぜでしょうか? 恐らくプログラムの内容はあまりないと思いますので概要だけ汲み取ってくれたら嬉しいです。因みにadd関数は途中です。

  • C言語 mallocによる消費メモリ

    char *b = (char *)malloc(sizeof(char) * 6) というC言語のプログラムで、消費されるメモリは何バイトになるのでしょうか?理由も合わせて教えていただきたいです。 32ビットのPCで行うものとしてよろしくお願いいたします。

  • fclose()でセグメンテーション違反

    C言語でのファイル読み込みで、ファイルを開いてデータを読み込んで表示することはできたのですが、最後のfclose(fp)でセグメンテーション違反になります。一番最後のwhileループをコメントアウトしたところセグメンテーション違反にはならなかったので、ここに何か問題があると思うのですが、どこが悪いのかが分かりません... #include<stdio.h> #include<stdlib.h> main(void){ FILE *fp; int i=0 , j=0 ,cnt = 0 , c=0; char *name="data.txt"; float *buf1,*buf2; if((fp = fopen(name,"r")) == NULL){ printf("error\n"); return 0; } else{ while((c = getc(fp)) != EOF) { if(c == '\n') cnt++; } printf(">>%d<<\n",cnt+1); rewind(fp); buf1 = (float *)malloc( (int)(cnt/2) +1); buf2 = (float *)malloc( (int)(cnt/2) +1); /*ここからがおかしい?*/ while(1){ if( fscanf( fp ,"%f %f",&buf1[i],&buf2[i])==EOF )break; printf("%f %f\n",buf1[i],buf2[i]); i++; } fclose(fp); } return 0; } なぜセグメンテーション違反になっているのでしょうか?

  • malloc関数について質問です。

    整数を入力してその分だけ動的にメモリを確保し、その後文字列を入力して確保した領域に格納し、表示するプログラムなんですが、 int main(void) { int n; char *p; puts("整数を入力"); scanf("%d", &n); p = malloc(sizeof(char) *(n+1)); puts("文字を入力");   scanf("%s", p); printf("文字列は%s\n", p); free(p); return 0; } としたら、ちゃんとプログラムは動くんですが、 問題の意図にあっているんでしょうか?

  • ヘッダファイル? malloc.hとかは自分で足したり作ったりできるのでしょうか

    CmachineでC言語を勉強していて、メモリの確保までたどり着きました。 でも、プログラムを実行できないんです。調べたところ、malloc.hやmemory.hがCmachineのincludeフォルダに入っていませんでした。 char *b; b = (char *)malloc(sizeof(char)*200); とか書いても実行できませんよね・・・。Cmachineは勉強するのに便利だし、ヘッダファイルを追加できないのでしょうか。includeフォルダにテキストファイルで書いて入れればできそうなのですが。 ちなみに、Visual C++ Express Editionでも同じプログラムを実行したのですが、できませんでした。あれもヘッダファイルが無いとかの問題なのでしょうか。あれは操作が複雑で難しくてよくわかりません。 アドバイスやいい方法をご存知の方、教えてください!!

専門家に質問してみよう