ページ 1 / 1
while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 17:29
by NBK
初めまして、UNMといいます。チラチラ覗きにきてはいつもお世話になっていました。
宜しくお願いします。
今勉強している双方向循環リストで困ったことが起きましたので、ご教授願います。
作っているプログラムでの構造体の中身は
・次データへのポインタ
・前データへのポインタ
・この構造体のステータス
の3つです。
ステータスは、リスト構造を始めから終わりまでループしたときの終了条件に使っています。
以下コードは頭から最後までをループで参照するプログラムなんですが、
ループ中にあるif内の実行文が実行されてない…と思われます。(37~47行目)
ifの条件式が間違っているのでしょうか。
他の何かが原因なのでしょうか?
宜しくお願いします。
コード:
typedef struct linkedlist{
struct linkedlist *NEXT_ptr;
struct linkedlist *PREVIEW_ptr;
struct linkedlist *STATUS;
}list_t;
int main(void){
list_t DUMMY;
list_t *HEAD;
list_t *END; ///mallocによる動的確保のコードは省略しました。
HEAD->NEXT_ptr = END;
HEAD->PREVIEW_ptr = END;
HEAD->STATUS = &DUMMY;
///リスト構造をHEADとENDでつくりました。
END->NEXT_ptr = HEAD;
END->PREVIEW_ptr = HEAD;
END->STATUS = NULL; ///ループの終了条件につかいます。
while(HEAD->STATUS != NULL)
{
int COUNT = 0;
printf("%d\n",COUNT++); ///ここまでは実行されます。
if(HEAD->STATUS == &DUMMY)
{
printf("SUCCESS-DUMMY\n"); ///実行されない
break; ///実行されない
}
else if(HEAD->STATUS == NULL)
{
puts("SUCCESS-NULL"); ///実行されない
printf("%d\n",COUNT); ///実行されない
}
HEAD = HEAD->NEXT_ptr;
}
free(HEAD);
free(END);
return 0;
}
実行結果
0
1
環境
OS: Ubuntu 11.04
コンパイラ: GCC 4.7
以上です。
宜しくお願い致します。
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 17:35
by みけCAT
Ideoneでのテスト(
http://ideone.com/kWXpVp)では、
と表示されました。
コードに全角スペースが混ざっているためコンパイルできず、古いプログラムを実行していると思われます。
オフトピック
NBK さんが書きました:mallocによる動的確保のコードは省略しました。
このまま実行すると、
runtime errorになりました。
無駄な省略はしないでいただけるとわかりやすいです。
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 17:51
by みけCAT
手元のコンパイラで
http://ideone.com/kWXpVpのコードのテストをしましたが、
と表示されました。
Windows Vista Home Premium SP2 32ビット
Intel(R) Core(TM)2 Duo CPU T8100 @ 2.10GHz 2.10GHz
RAM 4.00GB
コンパイラのバージョン
コード:
Using built-in specs.
COLLECT_GCC=C:\MinGW\bin\gcc
COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/4.7.0/lto-wrapper.exe
Target: mingw32
Configured with: ../gcc-4.7.0/configure --enable-languages=c,c++,ada,fortran,obj
c,obj-c++ --disable-sjlj-exceptions --with-dwarf2 --enable-shared --enable-libgo
mp --disable-win32-registry --enable-libstdcxx-debug --disable-build-poststage1-
with-cxx --enable-version-specific-runtime-libs --build=mingw32 --prefix=/mingw
Thread model: win32
gcc version 4.7.0 (GCC)
コンパイルオプション
コード:
>gcc -o if_else_noexec_470.exe if_else_noexec.c -static
>gcc -O2 -o if_else_noexec_470_O2.exe if_else_noexec.c -static
の2種類
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 18:09
by non
みけCATさんが言われてるように、実際に動かしているプログラムを載せてください。
コード:
typedef struct linkedlist{
struct linkedlist *NEXT_ptr;
struct linkedlist *PREVIEW_ptr;
struct linkedlist *STATUS;
}list_t;
このSTATUSって?どんなリスト構造を考えているのでしょう。
何を作ろうとしているのか理解できません。
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 18:13
by NBK
みけCATさん、ありがとうございます。
こちらでも実行できました・・・
お手間かけさせて大変にすみませんでした・・・
> このまま実行すると、runtime errorになりました。
> 無駄な省略はしないでいただけるとわかりやすいです。
申し訳ないです。
malloc/free用の関数を自分で作っていたので省略してしまいましたが、
単にmallocをそのまま書けばいいですね。
一応訂正版を貼っておきます。
コード:
/*
省略なしの訂正版です。
全角も・・・消えてると思います・・・
*/
typedef struct linkedlist{
struct linkedlist *NEXT_ptr;
struct linkedlist *PREVIEW_ptr;
struct linkedlist *STATUS;
}list_t;
int main(void){
list_t DUMMY;
list_t *HEAD = (list_t *)malloc(sizeof(list_t *));
list_t *END = (list_t *)malloc(sizeof(list_t *));
HEAD->NEXT_ptr = END;
HEAD->PREVIEW_ptr = END;
HEAD->STATUS = &DUMMY;
///リスト構造をHEADとENDでつくりました。
END->NEXT_ptr = HEAD;
END->PREVIEW_ptr = HEAD;
END->STATUS = NULL; ///ループの終了条件につかいます。
while(HEAD->STATUS != NULL)
{
int COUNT = 0;
printf("%d\n",COUNT++); ///ここまでは実行されます。
if(HEAD->STATUS == &DUMMY)
{
printf("SUCCESS-DUMMY\n"); ///実行されない
break; ///実行されない
}
if(HEAD->STATUS == NULL)
{
puts("SUCCESS-NULL"); ///実行されない
printf("%d\n",COUNT); ///実行されない
}
HEAD = HEAD->NEXT_ptr;
}
free(HEAD);
free(END);
return 0;
}
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 18:23
by NBK
nonさん、勝手に解決してしまいました・・・ごめんなさい・・・
> みけCATさんが言われてるように、実際に動かしているプログラムを載せてください。
実は、実際に動かしてるプログラムがすごい行数で説明するのもされるのも大変だと思ったので、
問題の箇所を抜き取るように小さい規模にして質問させていただきました。
> このSTATUSって?どんなリスト構造を考えているのでしょう。
> 何を作ろうとしているのか理解できません。
作ろうとしている構造は
HEAD <- -> DATA1 <- -> DATA2 <- -> DATA・・・<- -> END
というもので、HEADとENDもNEXT/PREVIEWポインタで繋がっています。
こういう循環リストを作ろうとしたとき、ループ条件をたとえば
while(HEAD->NEXT_ptr != NULL)
という式にしようと思ってましたが、循環になると無限ループに陥るので、
結局他に思い浮かばず、今はSTATUSというポインタにNULLポインタを入れることでループを終了させることにしました。
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 18:25
by non
>list_t *HEAD = (list_t *)malloc(sizeof(list_t *));
これって不味くないですか?
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 18:27
by みけCAT
include擬似命令も省略しないで欲しいです。
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 18:29
by non
NBK さんが書きました:作ろうとしている構造は
HEAD <- -> DATA1 <- -> DATA2 <- -> DATA・・・<- -> END
というもので、HEADとENDもNEXT/PREVIEWポインタで繋がっています。
これは、わかります。私がお尋ねしたいのは、STATUSが
struct linkedlist *STATUS;
になっている理由です。
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 18:36
by NBK
nonさん
>list_t *HEAD = (list_t *)malloc(sizeof(list_t *));
おかしい理由は、引数にはバイト単位で指定しなきゃいけないからですか・・・?
> struct linkedlist *STATUS;
言われてみると、こうでなければいけない理由はありません・・・
でもベストな方法を言ってみろといわれると、わかりません。
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 18:37
by NBK
みけCAT さんが書きました:include擬似命令も省略しないで欲しいです。
はい、ちゃんと修正できたら、ちゃんとしたものをアップしたいと思います・・・
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 18:57
by non
NBK さんが書きました:
>list_t *HEAD = (list_t *)malloc(sizeof(list_t *));
おかしい理由は、引数にはバイト単位で指定しなきゃいけないからですか・・・?
確保したいバイト数はいくらなのでしょうか?
仮に、ポインタ変数が4バイトだとしたら、あなたが確保したいのは
何バイトですか?
NBK さんが書きました:
> struct linkedlist *STATUS;
言われてみると、こうでなければいけない理由はありません・・・
でもベストな方法を言ってみろといわれると、わかりません。
間違っていると私は言っているわけではありません。どのような構造体を作りたいのでしょうか
と、お尋ねしているのです。このままでは、データを入れるメンバーがないのが気になっただけです。
テスト用ですからと言われれば、それで結構です。
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 19:08
by NBK
non さんが書きました:
確保したいバイト数はいくらなのでしょうか?
仮に、ポインタ変数が4バイトだとしたら、あなたが確保したいのは
何バイトですか?
確保したいのは1600バイトほど(=list_t型変数)です。
malloc(sizeof(list_t *)) はおかしいですね・・・
malloc(sizeof(list_t)) ですね・・・
non さんが書きました:
間違っていると私は言っているわけではありません。どのような構造体を作りたいのでしょうか
と、お尋ねしているのです。このままでは、データを入れるメンバーがないのが気になっただけです。
テスト用ですからと言われれば、それで結構です。
なるほど。はい、テスト用です。
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 19:12
by NBK
> 確保したいのは1600バイトほど(=list_t型変数)です。
> malloc(sizeof(list_t *)) はおかしいですね・・・
> malloc(sizeof(list_t)) ですね・・・
これウソです。ただのポインタ変数として使いたいです。
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 19:15
by NBK
>> 確保したいのは1600バイトほど(=list_t型変数)です。
>> malloc(sizeof(list_t *)) はおかしいですね・・・
>> malloc(sizeof(list_t)) ですね・・・
>これウソです。ただのポインタ変数として使いたいです。
全部ウソです(泣)すみません(泣)
HEADもENDも12バイトあれば事足ります。
NEXT/PREVIEW/STATUSの分なので。
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 19:19
by non
NBK さんが書きました:
malloc(sizeof(list_t)) ですね・・・
そうだと思います。
NBK さんが書きました:
HEADもENDも12バイトあれば事足ります。
NEXT/PREVIEW/STATUSの分なので。
HEADやENDはポインタですから4バイトです。
HEADやENDが指している構造体が12バイトですね。
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 19:35
by NBK
non さんが書きました:
HEADやENDはポインタですから4バイトです。
HEADやENDが指している構造体が12バイトですね。
なるほど。
つまりHEADでいえば、
HEAD = (list_t *)malloc(12);
ということですか?
HEADというポインタ変数に、確保された12バイト分のメモリ領域の先頭アドレスが代入される。
なんだか頭が混乱してきました・・・
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 19:36
by みけCAT
ポインタのサイズは4バイトとは限りません。
HEAD = (list_t *)malloc(sizeof(list_t));
としてください。
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 19:37
by NBK
みけCAT さんが書きました:ポインタのサイズは4バイトとは限りません。
HEAD = (list_t *)malloc(sizeof(list_t));
としてください。
僕の環境だと4バイトでした。
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 19:46
by みけCAT
NBK さんが書きました:みけCAT さんが書きました:ポインタのサイズは4バイトとは限りません。
HEAD = (list_t *)malloc(sizeof(list_t));
としてください。
僕の環境だと4バイトでした。
compileonline</>comだと8バイトのようです。
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 20:01
by NBK
あ、CPUによって違うんですね・・・
じゃあバイトを数値で記述するのは良くないんですね。
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 20:10
by non
そうですよ。だから最初に4バイトと仮定したらって書いてます。
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 20:14
by NBK
コードちゃんとしたのを載せます。
お二人に言われた部分を書き換えました。
ありがとうございました。
コード:
#include <stdio.h>
#include<stdlib.h>
typedef struct linkedlist{
struct linkedlist *NEXT_ptr;
struct linkedlist *PREVIEW_ptr;
struct linkedlist *STATUS;
}list_t;
int main(void){
list_t DUMMY;
list_t *HEAD = (list_t *)malloc(sizeof(list_t));
list_t *END = (list_t *)malloc(sizeof(list_t));
HEAD->NEXT_ptr = END;
HEAD->PREVIEW_ptr = END;
HEAD->STATUS = &DUMMY;
END->NEXT_ptr = HEAD;
END->PREVIEW_ptr = HEAD;
END->STATUS = NULL;
while(HEAD->STATUS != NULL)
{
int COUNT = 0;
printf("%d\n",++COUNT);
if(HEAD->STATUS == &DUMMY)
{
puts("SUCCESS_DUMMY\n");
}
HEAD = HEAD->NEXT_ptr;
}
if(HEAD->STATUS == NULL) puts("SUCCESS-NULL");
return 0;
}
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 20:15
by NBK
non さんが書きました:そうですよ。だから最初に4バイトと仮定したらって書いてます。
完全に読み飛ばしてました・・・
こんなアホに付き合ってくれてありがとうございました。
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 20:48
by みけCAT
NBK さんが書きました:
あ、CPUによって違うんですね・・・
じゃあバイトを数値で記述するのは良くないんですね。
利点はもう一点あります。
例えば
コード:
struct hoge {
int value1[123];
short value2[31];
char value3[1023];
char value4[14];
int value5[11];
double value6[634];
};
こんな構造体の要素を確保したいと思ったらどうしますか?
このサイズをいちいち手計算するのは大変ですし、アラインメントの問題もあります。
さらに、サイズを直接書く場合、構造体の中身を書き換えたら領域を確保している部分全てを書き換えないといけなくなります。
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 21:27
by NBK
みけCAT さんが書きました:
利点はもう一点あります。
例えば
コード:
struct hoge {
int value1[123];
short value2[31];
char value3[1023];
char value4[14];
int value5[11];
double value6[634];
};
こんな構造体の要素を確保したいと思ったらどうしますか?
このサイズをいちいち手計算するのは大変ですし、アラインメントの問題もあります。
さらに、サイズを直接書く場合、構造体の中身を書き換えたら領域を確保している部分全てを書き換えないといけなくなります。
おお。確かにそうですね。
defineマクロもそうですが、形に置き換えることで汎用性が高まりますね。
ありがとうございます。
あの・・・アラインメントについて質問させてください。(たくさんお世話になって申し訳ないです。)
構造体をバイナリ形式でファイルに書き込むのは危険ですが、
その形式を使用しながらもバグを起こさない方法はどういうものがありますか?
#pragma packというマクロを見たことはありますが、使い方がさっぱりでした。
色々考えたりしたものの、解決できなくて・・・
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 21:31
by みけCAT
その形式ってどの形式ですか?
バイナリ形式を使いたいなら、wavやbmpのように独自のファイルフォーマットを決めて書き込めばいいです。
Re: while内にあるif-elseの実行文が実行されない原因
Posted: 2013年8月18日(日) 21:59
by NBK
みけCAT さんが書きました:その形式ってどの形式ですか?
バイナリ形式を使いたいなら、wavやbmpのように独自のファイルフォーマットを決めて書き込めばいいです。
あ、なるほど。ありがとうございました。