free()関数 と segmentation fault

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
きっど

free()関数 と segmentation fault

#1

投稿記事 by きっど » 16年前

はじめまして。
現在、大学の卒研でプログラムを作っているのですが、segmentation faultを
取り除けない状態で苦しんでいます。

ファイルを添付させていただきます。これはコンパイル・実行は出来ますが、
途中で停まります。

停まったところには直前に"break point"と書かせて頂きました。
break point1はノートPC OS:Linuxで、2は学校PC OS:Free BSD
で起きました。ともにGCCです。

break point2の free(tmp)の直前では tmpの中身を表示(アクセス)しても異常
はなかったのですが、そこでsegmentation faultが起きました。
関数snapBetaを付け加えてからこのような症状が出ています。

長めのプログラムですが、どなたかミスを指摘して頂けたら幸いです。
よろしくお願いいたします。


toyo

Re:free()関数 と segmentation fault

#3

投稿記事 by toyo » 16年前

ちょっと長いのでコメントを書いてもらうと見るほうも助かりますよ
質問とはぜんぜん関係ないですがcalloc( )という0で初期化してくれる関数もあります

box

Re:free()関数 と segmentation fault

#4

投稿記事 by box » 16年前

何をするプログラムかもわからず、
コメントが全くついていないコード
(変数や関数の意味がわからない)を
読めといわれましても、苦痛を伴うだけです。

Mist

Re:free()関数 と segmentation fault

#5

投稿記事 by Mist » 16年前

snapBeta関数をきちっとデバッグしたほうがいいんじゃないかな?

free(dec_m);

の下に

dec_m = NULL;

を追加してみたらsnapBeta関数終了時にはdec_mは常にNULLになっていてメモリが確保された状態でこの関数を終了することがないようです。
SuperIncreaseAWからOFFが返るとそうなるけど、snapBetaの呼び元はそれを想定していないですよね。
そのために、free(dec_m_sort)で100%落ちます。
break pointと書かれているところでどうして落ちるのかはわからないです。
私の環境では問題なかったです。

non

Re:free()関数 と segmentation fault

#6

投稿記事 by non » 16年前

2重ポインタってこんな使い方できるんですかね?
あんまり使ったことがないので、詳しい人にコメントもらいましょう。
double **DoubleArray2d(int m,int n)
{
  double **array;
  int j,k;
  array=(double **)malloc(m * sizeof(double *));
  array[0]=(double *)malloc(m * n * sizeof(double));
  for(j=1; j<m; j++) { array[j]=array[0]+j*n; }
  for(j=0; j<m; j++){
    for(k=0; k<n; k++){
      array[j][k]=0;
    }
  }
  return array;
}
この関数でポインタ配列を指す2重ポインタを作って、2重ポインタが指すポインタでm*n個のデータを指す。
次に、2番目以降のポインタが指す場所を計算している。最後にすべて0クリアー。
まぁ、ここまではそんなもんかなぁなんですが。
プログラムを全部見てないので、何のためにこんなことが必要なのか分かってないのですが、配列の長さが
可変でないなら、2重ポインタにする必要はどこにあるのだろうって思っちゃいました。

呼び出しは
double **tmp;
tmp = DoubleArray2d(BLOCK, 2);

そして、freeのとき
free(tmp);
がしてありますが、これでは、
array=(double **)malloc(m * sizeof(double *));のポインタ配列分を解放しただけで、
array[0]=(double *)malloc(m * n * sizeof(double));の分は解放していないのではないのしょうか?

詳しい方へ!!
このfree一発で、2回のmallocで確保したメモリーをすべて解放しますか?

御津凪

Re:free()関数 と segmentation fault

#7

投稿記事 by 御津凪 » 16年前

> このfree一発で、2回のmallocで確保したメモリーをすべて解放しますか?
free(tmp);
は、
(double **)malloc(m * sizeof(double *));
で作成されているデータだけ(ポインタの配列)を開放します。

(double *)malloc(m * n * sizeof(double));
は、別領域として確保されるため、開放されません。
一発でやるなら、

double **DoubleArray2d(int m,int n)
{
  double **array;
  int j,k;
  array=(double **)malloc(m * sizeof(double *) + m * n * sizeof(double **));
  array[0]=(double *)(array + m);
  for(j=1; j<m; j++) { array[j]=array[0]+j*n; }
  for(j=0; j<m; j++){
    for(k=0; k<n; k++){
      array[j][k]=0;
    }
  }
  return array;
}
だと思います。

non

Re:free()関数 と segmentation fault

#8

投稿記事 by non » 16年前

へぇ~ですね。
array=(double **)malloc(m * sizeof(double *) + m * n * sizeof(double **));
ここは double じゃないのですか?

御津凪

Re:free()関数 と segmentation fault

#9

投稿記事 by 御津凪 » 16年前

> ここは double じゃないのですか?

あー、間違えていますね。 double が正しいです。

box

Re:free()関数 と segmentation fault

#10

投稿記事 by box » 16年前

> 2重ポインタってこんな使い方できるんですかね?
> あんまり使ったことがないので、詳しい人にコメントもらいましょう。
>   array[0]=(double *)malloc(m * n * sizeof(double));
>   for(j=1; j<m; j++) { array[j]=array[0]+j*n; }

私は、たぶん、上の2文をこんな風に書くと思います。

   for (j = 0; j < m; ++j) {
      array[j] = malloc(sizeof(double) * n);
   }


> このfree一発で、2回のmallocで確保したメモリーをすべて解放しますか?

しないです。

non

Re:free()関数 と segmentation fault

#11

投稿記事 by non » 16年前

boxさん
私も、2重ポインタにするなら、そう書きます。
でも、このプログラムなら2重ポインタにしませんけどね。
恐らく。プログラムを見るのは止めましたから・・

box

Re:free()関数 と segmentation fault

#12

投稿記事 by box » 16年前

> でも、このプログラムなら2重ポインタにしませんけどね。
> 恐らく。プログラムを見るのは止めましたから・・

プログラムの仕様上、必要があれば使わざるを得ないのではないでしょうか。
二重ポインタを使わない、とおっしゃっている根拠が薄弱です。

きっど

Re:free()関数 と segmentation fault

#13

投稿記事 by きっど » 16年前

皆様どうもご親切に教えていただきましてありがとうございました。
ようやく解決しました。

プログラムにコメントを付けなくて申し訳なかったです。これは、ある暗号の攻撃法です。

閉鎖

“C言語何でも質問掲示板” へ戻る