• 締切済み

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(); //セグメンテーションエラー 特に多次元配列を作成したり、動的確保を大目にすると起こりやすいです。 もし何かお気付きのことがありましたらよろしくお願いします。

みんなの回答

  • ko_kinta
  • ベストアンサー率39% (43/109)
回答No.5

arrXのmallocサイズが最大10個なのに、 const int numHokan=40; … arrX=(double *)malloc(sizeof(double)*(N+1)); … for(incA=0;incA<=numHokan;incA++){ arrX[incA]=Setx(incA); } これではおもいっきりオーバーフローしています。 他にもいくつか突っ込みどころはありますが、ちゃんと動いていますか?

sirooni
質問者

補足

すいません。実はまだバグ取り(コンパイルエラー以外)段階なので色々ミスってるかもしれません。動的確保の部分以外をキチンとしてからの方がはっきりしますね。 出直してきます

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

for(incA=0;incA<=numHokan;incA++){ arrX[incA]=Setx(incA); } ですが、numHokan=40の為、 arrX[40]=Setx(40);の状態が発生します。 ところが、 arrX=(double *)malloc(sizeof(double)*(N+1)); であり、N=2の場合、3個しか確保していません。 ここで、メモリを壊していませんか。

  • ko_kinta
  • ベストアンサー率39% (43/109)
回答No.3

N==0の場合、 arrCn=(double **)malloc(sizeof(double *)*(N+2)); これは2個の配列のアドレスを格納するための領域確保になりますね。 arrCnに値を格納するための領域をmallocしているfor文 for(incA=0;incA<=N;incA++){ これだとarrCn[0]に4個の領域が確保されるだけです。 値を格納しているfor文 for(incA=1;incA<N;incA++){ これは1回も実行されることなくループを抜けます。 最初のprintf関数 printf("%lf",arrCn[1][1]);getchar(); //取れる ここで領域外を参照していますが、想定どおりの値が取れているのでしょうか?。 ふたつのfor文のループ条件部分は"incA<N+2"でなければならないのでは?

sirooni
質問者

補足

すいません。N(2~9)の間違いです。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

とりあえず、動作するプログラムを貼ってもらわないと、原因の特定は無理です。

sirooni
質問者

補足

ありがとうございます。 http://sirooni.moe.to/spu.c ここに用意しました。

回答No.1

一番多いケースがメモリリークでしょうね。 配列を使う場合に特にミスし易いです。

関連するQ&A

  • 関数内での多次元配列のメモリの動的確保について

    関数内で、参照渡しをして配列の動的なメモリの確保をしようとしているのですが、うまくいきません。 はじめに、main関数内で、 int main(void){ double *testdata1; testdata1 = (double*)malloc( sizeof(double) * 10 ); if( testdata1 == NULL ){ printf( "ERROR:testdata1" ); exit(0); } testdata1[3] = 20.4; printf( "test = %g\n", testdata1[3] ); } を実行したところうまくいきました。 そこで、 int main(void){ double *testdata1; Kakuho( &testdata1 ); printf( "test = %g\n", testdata1[3] ); } void Kakuho( double **testdata2 ){ *testdata2 = (double*)malloc( sizeof(double) * 10 ); if( *testdata2 == NULL ){ printf( "ERROR:testdata2" ); exit(0); } *testdata2[3] = 20.4; } としましたが、成功してくれません。 コンパイルは通りますが実行するとエラーが発生して落ちます。 (上記のprintfのERRORではありません。) 動作環境はXPのVCC7です。よろしくお願いします。

  • テキストの読み込みとmalloc()についてです

    こんにちは。 二つのベクトルの次元と要素をテキストファイルから読み取ってそのベクトルの和を出したいのですがうまくいきません。 #include <stdio.h> #include <stdlib.h> double vector_sum(double *x, double *y, int n){ int i; double z[256]={0}; for(i=0;i<n;i++){ z[i] = x[i] + y[i] ; } return *z; } //ベクトル和を出す関数(のつもり)// int main(void){ int i,j,e; double *a,*b,c[256][256]; //a,bはベクトル// FILE *fp; char fname[64]; char str[256]; double z[256]; printf("二つのベクトルが書き込まれているファイル名を入力してください."); scanf("%s",fname); fp = fopen(fname,"r"); if(fp==NULL){ printf("そのようなファイルを見つけることができません。"); } while (fgets(str, 256, fp) >= 0) { i++; fgets(str, 256, fp); printf("%s",str); //テキストの読み取り// if(fgets(str,256,fp)==NULL) break; //読み取り終了時の動作// sscanf(str,"%lf", &c[i]);//c[i][0]は要素数、c[i][1以上]はベクトルの中身を指すことにする。// printf("%lf%lf%lf%lf%lf%lf%lf%lf\n",c[0][0],c[0][1],c[1][2]); if(sscanf(str,"%lf", &c[i])<1){ printf("Format error"); } } if(c[0][0]!=c[1][0]){ printf("要素数が違います。"); } a = malloc(sizeof(double) * c[0][0]); b = malloc(sizeof(double) * c[1][0]); if(a==NULL||b==NULL){ printf("記憶領域の確保に失敗しました。"); } e = c[0][0]; //要素数// for(i=0;i<=e-1;i++){ a[i]=c[0][i+1]; //ベクトルの中身のみをa,bに代入する。// b[i]=c[1][i+i]; } *z= vector_sum(a,b,e); printf("ベクトル和は{"); for(i=0;i<=e-1;i++){ printf("%lf,",z[i]); } printf("}です。"); return 0; } テキストファイルは下のものを使いました。(ファイル名はvector.txt) element: 7 { 4, 4 ,4 ,4 ,4 ,4 ,4 } element: 7 { 8, 8, 8, 8, 8, 8, 8 } 結果は 「二つのベクトル名が書き込まれているファイルを入力してください。(vector.txtを入力) element: 7 { 8, 8, 8, 8, 8, 8, 8 } 要素数が違います。記憶領域の確保に失敗しました。ベクトル和は{}です。」 と表示されてしまい、困っています。 初歩的なミスかもしれず恐縮ですがよろしければ回答お願いします。

  • mallocによる確保外の領域への参照

    構造体をmallocにより動的確保を行っていたのですが、例えば typedef struct _point{ int x, y; } point; point *pelem_point; pelem_point = (point *)malloc(sizeof(point)*5); このように、point型の構造体を5つ確保するとします。 しかし、 (pelem_point+100)->x = 1; (pelem_point+100)->y = 2; printf("%d\n", (pelem_point+100)->x); printf("%d\n", (pelem_point+100)->y); とやったら、確保していない100個先のところも構造体として利用できました。 なぜなのでしょうか。 自分の考えではこのようになりました。 mallocによりヒープ領域から適当な空いているメモリのアドレスが渡されるため、そこからはヒープ領域より先に、限りがあるまで進めてしまうために確保外のサイズにアクセスしても使えてしまっている。 また、mallocにより確保した場合は使用中のラベルがはられるため他に侵されることはないが、先の例のようにmallocによって確保してない場合はいくら使用できたとしても、空いているとコンピュータでは認識されるため、何かヒープ領域を使う場合に勝手に上書きされてしまう可能性がある。 しかし、この考えでも、なぜ確保外の領域が構造体のサイズ分ずつ区切られているのか納得いきません。 わかる方いましたらよろしくお願いします。

  • malloc関数について。

    typedef struct a{ char *simei; int nenrei; }MEIBO; void main(void) { MEIBO a[5]; int wa; for(i = 0; i <= 4; i++ ) { a[i].simei = malloc(100 * sizeof(char) ); if( a[i].simei == NULL ) /* 領域確保に失敗したか */ { printf( "%dバイトの領域確保に失敗", 100 * sizeof(char) ); return 1; } printf("%d番目を入力してください\n",i+1); scanf("%s",&a[i].simei); printf("%s\n",a[i].simei); } C言語初心者です。これで入力したa[i].simeiが表示されないのですが、間違いを指摘していただけますでしょうか。宜しくお願いします。

  • 動的なメモリ領域の確保

    double型変数5個分のメモリをmalloc関数により確保し,その確保した要素のアドレスを表示するように,プログラムを作る問題で、 (注)に「 %pで表示するためには,double型へのポインタ(double *)をvoid型へのポインタ(void *)にキャストする必要がある.」と書かれていたのですが、どういうことでしょうか? 以下のようでいいのでしょうか? #include<stdio.h> #include<stdlib.h> #define COUNT 5           // 動的に確保するメモリ領域数を示すマクロ定数の定義 int main(void) {  // 動的に確保するメモリ領域のアドレスを保持するポインタ変数の宣言  double * pointer;  int i;                  // for文で使用する変数の宣言  // int型変数5個分のメモリ領域を確保  pointer = (double *)malloc(sizeof(double) * COUNT);  if(pointer == NULL) {        // メモリ領域の確保が失敗した場合   printf("メモリ領域を確保できませんでした.\n");   exit(1);                // プログラムの終了  }  for(i = 0; i < COUNT; i++)   printf("%d番目のアドレスは%pです.\n", i + 1, pointer + i);  free(pointer);            // 確保したメモリ領域の解放  return 0; }

  • malloc関数によるメモリの確保

    C初心者です。 malloc関数によるメモリの確保に関して教えてください。 2次元配列のサイズに対してmalloc関数の引数値をたとえば、 (double*)malloc(datasize*sizeof(double)) などとしメモリ領域を確保すると、メモリアドレスはデータのサイズ によらず一定 1234044、1234048となります。 データサイズを大きくし、datasize*sizeof(double)が16Kバイトを超えるとcmd.exeがエラーとなり落ちます。 デバックモードで実行すると 「"System.AccessViolationException"のハンドルされていない例外が不明なモジュールです。で発生しました。 追加情報:保護されているメモリに読み取りまたは書き込み操作を行おうとしました。他のメモリがこわれていることが考えられます」 というメッセージがでます。 コンパイラはExpressEdition2008です。 この現象を回避するにはどうすべきか、なぜこのようなことが起こるのかご教授ください。 よろしくお願いいたします。

  • qsortと動的確保の2次元配列

    C言語で以下のようなソートのあるプログラムを作ろうとしているのですが、良い方法が思いつきません。。。。 どなたか,知恵を貸していただけないでしょうか? ・複数人の身長と体重がcsvファイルに2列に入っている。 人 身長 体重 1 158.9 50.5 2 161.2 72.3 3 150.4 42.8 4 170.7 80.4 5 165.0 59.9 ・ ・ ・ ・ ・ ・ ・↑このように身長も体重もランダムに並んでいる状態 ・身長・体重をプログラムで読み込んだら 身長の低い順にソートする。この時体重も身長に対応して並び換わってほしい。 (わかりやすいかと思い人の番号列を設けましたが、人の番号は考えなくて良いです) この問題に対して,データ数が不特定かつ多いため 動的確保の2次元配列を使ったクイックソートで対応を考えます。 qsortについてあれこれ調べていたのですが,動的確保でのqsort例が無く困っています。。。 どなたかちょっとアドバイスをいただけないでしょうか? よろしくお願いします。 #include <stdio.h> #include <stdlib.h> enum {HIGHT, WEIGHT, COLUMN}; int comp (const void *a, const void *b) //比較関数 { return (int) (((double *)a)[HIGHT] - ((double *)b)[HIGHT]) ; } int main(void) { ////////////////////////////////////////////////////////// 私情により、ソート以前の処理で使用するため あらかじめ .csv ファイルから fget で値を読み込んで コンマで分割しx[]y[]に格納してある。 &データ数をカウントしている 今は省略  仮定として以下のように5つのデータ数を読み込んでいたとする double x[5] = {158.9,161.2,150.4,170.7,165.0}; double y[5] = {50.5,72.30,42.8,80.4,59.9}; int n=5; //データカウント数 /////////////////////////////////////////////////////////// int i; double **list; list = (double**)malloc(sizeof(double)*5); for (i=0 ; i< 5 ; i++) { list[i] = (double*)malloc(sizeof(double)*COLUMN); if (list[i]==NULL) return 1;/* 領域確保に失敗したか */ } for(i=0;i<n;i++) { list[i][HIGHT]=x[i]; list[i][WEIGHT]=y[i]; } for(i = 0; i < n; i ++) printf("%lf %lf\n", list[i][HIGHT], list[i][WEIGHT]); puts("Sort"); qsort(list,n, sizeof(double [COLUMN]), comp); for(i = 0; i <n; i ++) printf("%lf %lf\n", list[i][HIGHT], list[i][WEIGHT]); scanf("%d",i); return 0; }

  • メモリ動的確保について

    こんにちはです。 メモリの動的確保なのですが、 typedef struct DATA{ char name[256]; char pass[256]; int money; }BANK; void insert(BANK *p,int max); int main(){ int i; size_t st; BANK *person; person = (struct DATA *)malloc(sizeof(struct DATA)); //person = (struct DATA *)malloc(5); if(person == NULL){ printf("確保失敗\n"); exit(-1); } //memset(person,'\0',sizeof(struct DATA)); と、言う風に、記載ソースは途中ですがメモリをとりました。 mallocの後ろの部分ですが、sizeof(struct DATA)と5ではどうちがうのでしょう??2通りともコンパイルエラーはないです。 5は動的に最大5までとるって事はわかるのですが、struct DATAの方はいくつとるのです??いくつもで入力次第です? そして、動的したのにたいしてmemsetしたら実行エラー(コンパイルは通りました)おきました。動的にたいしてmemはダメなのでしょうか? アドバイスいただけたらありがたいです。宜しくお願いいたします。

  • c言語のmalloc()とエラー表示

    .malloc()については以前も質問させて頂きましたが 新たな疑問についてご教示下さい。 ・下記のプログラムでmalloc()とrealloc()は正常に作動していると思いますが、入力表示を有効にすると下記の「エラー表示」が表示されます。 ・「エラー表示」されてもプログラムは最後まで実行される様です。 ・n=400までは表示されます。 ・この理由が分かりません、ご教示下さい。 ・malloc()関係は不安定な関数群でしょうか? ■「エラー表示」について *********************************************************** 問題が発生したため、***.exeを終了します。ご不便をおかけて申し訳ありません。 作業途中・・・・・ この問題を「マイクロソフト」に報告ください。 ************************************************************ ・一部ですが以上の様なエラー表示です。 //malloc_2 #include <stdio.h> #include <stdlib.h> void MylnOut(int ,int ,int *); //************************************************************** // MAIN //************************************************************** int main() { int *map; int X=10,Y=10,n; /* 疑似2次元配列確保と初期表示 */   printf("初期値.... \n");   map=(int *)malloc(sizeof(X*Y)); // MylnOut( X, Y, map); /* 変更数値入力 */ for(n=1;n<401;n++){   X=rand()%50+2;   Y=rand()%50+2;   printf("変更..%3d回目 X=%2d Y=%2d\n",n,X,Y); /* 領域変更と表示 */   map=(int *)realloc(map,sizeof(X*Y)); // MylnOut( X, Y, map); } /* 領域開放 */   free(map);   map=NULL; return 0; //************************************************************** // 入力・表示 //************************************************************** void MylnOut(int X,int Y,int *map) {   int i,j;   for(j=0;j<Y;j++)    for(i=0;i<X;i++) map[j*Y+i]=X;   for(j=0;j<Y;j++){    for(i=0;i<X;i++) printf("%3d",map[j*Y+i]);    printf("\n");   } } ・コンパイルエラーは無く実行時エラーです。 .Borland C++ Compiler 5.5.1,TuboDebugger 5.5を使用しています。

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

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

専門家に質問してみよう