質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

1回答

1425閲覧

c言語 にて構造体の中身が消えるバグ

y_huto

総合スコア3

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

1クリップ

投稿2021/10/02 07:03

cの構造体(?)について質問があります。
以下のコードにて、途中で何故か構造体のs[t]->geneが全部なくなってしまうということが起こっております。

c

1void initialize_population(n, l) 2int n; /* number of strings */ 3int l; /* string length */ 4{ 5 int i, j, k, max_i; 6 double max_f; 7 char household_list[l * 32]; 8 9 //個体集団初期化 10 s = (String *)malloc(sizeof(String)*n); 11 if(s == NULL) printf("malloc failure for strings"); 12 13 //エリート初期化 14 elite = (String)malloc(sizeof(struct string)); 15 if(elite == NULL) printf("malloc failure for elite"); 16 elite->gene = (char *)malloc(sizeof(char)*l* 32); 17 if(elite->gene == NULL) printf("malloc failure for elite->gene"); 18 19 //n個の個体確保 20 for(i = 0; i < n; i++) { 21 s[i] = (String)malloc(sizeof(struct string)); 22 if(s[i] == NULL) printf("malloc failure for s[i]"); 23 24 s[i]->gene = (char *)malloc(sizeof(char)*l* 32); 25 if(s[i]->gene == NULL) printf("malloc failure for s[i]->gene"); 26 27 //初期世帯生成 28 make_household_list(household_list, l); 29 30 for(j = 0; j < l* 32; j++) { 31 s[i]->gene[j] = household_list[j]; 32 } 33 34 //適応度計算 35 s[i]->fitness = fitness_all(i, s[i]->gene, l); 36 s[i]->length = l; 37 38 //遺伝子確認1 39 for(j = 0; j < l* 32; j++) { 40 printf("%d,",s[i]->gene[j]); 41 } 42 printf("\n"); 43 44 } 45 46 //遺伝子確認2 47 for(i = 0; i < n; i++) { 48 if(s[i]->gene == NULL) printf("malloc failure for s[i]->gene\n"); 49 for(j = 0; j < l* 32; j++) { 50 printf("%d,",s[i]->gene[j]); 51 } 52 } 53 printf("\n"); 54 55}

"//n個の個体確保"のfor文の部分ではループがうまく全て実行されており、
このfor文の中で行われている
"//遺伝子確認1"では,ループ毎に個体数分の個体sのgene要素s[i]->gene[j]が全て表示されます。

しかし、そのforループが全て終わり、その後
"//遺伝子確認2"にてgeneを確認しようとすると、s[i]->geneが消えており、
if(s[i]->gene == NULL)の場合に表示される
"malloc failure for s[i]->gene"
が表示され、その後も表示されずに
Segmentation fault (コアダンプ)
が起こってしまいます。

以上なのですが、自分では解決方法がわからないのでご相談させていただきました。
make_household_list()と、fitness_all()の部分では、s[]->geneに対して初期化や代入、free()など値が変化するようなことは行っておりません

解決策や怪しい部分をご教授願います。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2021/10/02 08:03

s と、Stringの定義を提示しよう
jimbe

2021/10/02 08:16

> 値が変化するようなことは行っておりません それは、実際に値が変化しているのであれば、「行っていない"つもり"」という意味にしかならないのではないでしょうか。 s がグローバルになっている以上、どこでどう間違ってしまっているかは見なければ分かりません。気付かないうちにコピペの途中で変な所でペーストしてしまってたまたまコンパイルエラーも無く通ってしまっている可能性すらあるのですから。
y_huto

2021/10/02 14:08

そうですよね、ありがとうございます。 もう一度ここ以外のコードも確認してみます。
guest

回答1

0

ベストアンサー

(なんか変なのが送られてしまった...修正。)

ソースを眺めた範囲では「これはダメ」に気が付きませんでしたが。
「歴史的」な引数の宣言をしておいてC99以降の可変長配列使っている辺り妙な感じは否めませんがそれはともかく。

自分では解決方法がわからない

それはちょっと甘いかなぁ...その症状が100%出るのなら、
if(S[0]->gene==NULL){printf("N:%d****NULL****\n",i);}
のような"プローブ"を随所に挟んで

C

1 //n個の個体確保 2 for(i = 0; i < n; i++) { 3 s[i] = (String)malloc(sizeof(struct string)); 4 if(s[i] == NULL) printf("malloc failure for s[i]"); 5 6 s[i]->gene = (char *)malloc(sizeof(char)*l* 32); 7 if(s[i]->gene == NULL) printf("malloc failure for s[i]->gene"); 8if(S[0]->gene==NULL){printf("0:%d****NULL****\n",i);} 9 //初期世帯生成 10 make_household_list(household_list, l); 11if(S[0]->gene==NULL){printf("1:%d****NULL****\n",i);} 12 for(j = 0; j < l* 32; j++) { 13 s[i]->gene[j] = household_list[j]; 14 } 15if(S[0]->gene==NULL){printf("2:%d****NULL****\n",i);} 16 //適応度計算 17 s[i]->fitness = fitness_all(i, s[i]->gene, l); 18if(S[0]->gene==NULL){printf("3:%d****NULL****\n",i);} 19 s[i]->length = l; 20 21 //遺伝子確認1 22 for(j = 0; j < l* 32; j++) { 23 printf("%d,",s[i]->gene[j]); 24 } 25 printf("\n"); 26if(S[0]->gene==NULL){printf("4:%d****NULL****\n",i);} 27 } 28if(S[0]->gene==NULL){printf("5:%d****NULL****\n",i);} 29 //遺伝子確認2

で、どこかで引っかかるはずですから最初にどこで引っかかったかで発生原因/対策方法を大幅に絞れるはずです。
(__LINE__というマクロがソースコードの行数に置換されると知っていればプローブを
if(S[0]->gene==NULL){printf("%d:%d****NULL****\n",__LINE__,i);}
とすることで入れたり外したりしてもID?の編集をしなくてもよい、なんて小技はありますが)

投稿2021/10/02 08:16

編集2021/10/02 08:29
thkana

総合スコア7703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_huto

2021/10/02 14:18

ありがとうございます。__LINE__で調べることはすでに行っておりまして、 //n個の個体確保のfor内ではひっかからずに正常に動いていて、 //遺伝子確認2の if(s[i]->gene == NULL) printf("malloc failure for s[i]->gene\n"); まではうまく動いてjに関するfor内の(i,j)=(0,0)の時のprintfで止まってしまいます。 他の方もおっしゃっていますが、 値を変化させる操作を「行っていない"つもり"」かもしれないので他の箇所も見ているのですが、 正常に動いていた時と変えている箇所がなくてお手上げな状態です。
thkana

2021/10/02 15:24

> __LINE__で調べることはすでに行っておりまして、 では、実際にどこからS[0]がNULLになっているのか(どこまではS[0]がNULLでないのか)を具体的に示してください。それはとても重要な情報です。 > 正常に動いていた時と変えている箇所がなくてお手上げな状態です。 正常に動いていた時、というのがあるのですか? それはとても重要な情報に思えるのですが。
thkana

2021/10/02 15:42

いうまでもなく、S[0]->geneがNULLでなかった最後の場所からS[0]->geneがNULLになった最初の場所までの間に行った操作が一番の容疑者です。その間の処理を徹底的に調べます。他の関数を呼んでいたりするのなら、その関数の中でも同様にS[0]->geneを調べて、同様にNULLになるところを特定します。 これを続けていけば、「この一つの文の前後でS[0]->geneがNULLに変化する」というところが見つかるでしょう。きっとそこにはなにかの間違いが含まれているでしょうから、どうしてS[0]->geneがNULLになるかを考え、本来どう動くべきかを考えて、修正する、という道筋になるかと思います。
jimbe

2021/10/02 15:47 編集

このような場合は、ロジックを追ってはいけません。とにかく通る所には、最悪全コードの行数を二倍にするぐらいのつもりで片っ端から s[0]->gene の表示・チェックを入れて動きを見ては如何でしょうか。 池の水の中で巨大な網を振り回すより、池の水を全部抜いて一網打尽です。 ながら書きしてて thkana さんの書き込みと被ってしまいました^^;
thkana

2021/10/02 16:12

jimbeさん > ロジックを追ってはいけません 「いけません」はちょっと言いすぎかも? ロジックを追って誤りを見つけられればよいのですが、「自分のやったことは間違っていないはず」という思い込みで目が曇ってしまって、その曇った目でロジックを追っても間違いが見つからない(目の前の間違いに気がつけない)ことが現実としてままあるのです。これは別に質問者さんを責めているわけじゃなくて、誰にでも普通にあることです。だから、一目瞭然の事実を積み上げて「ここまではあっている」「ここからはあっていない」確認することがとても有効な場面というのがしばしば出てくるわけで。
jimbe

2021/10/02 21:07

すいません、「ロジックを追ってはいけない」は常に自分自身に言い聞かせていることなので、ついそのまま書いてしまいました。 もちろんどなたも責めるつもりは全くありません。
y_huto

2021/10/04 00:37

お二方、貴重なご意見ありがとうございました。 結果的に、s[0]->geneを操作していない箇所(fitness_all()の中身)が悪さをしておりましたが、 お二方に教えて頂いたとおり全行で表示・チェックを行って発見に至りました。 誠にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問