while内にあるif-elseの実行文が実行されない原因

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

while内にあるif-elseの実行文が実行されない原因

#1

投稿記事 by NBK » 10年前

初めまして、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

以上です。
宜しくお願い致します。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: while内にあるif-elseの実行文が実行されない原因

#2

投稿記事 by みけCAT » 10年前

Ideoneでのテスト(http://ideone.com/kWXpVp)では、

コード:

0
SUCCESS-DUMMY
と表示されました。
コードに全角スペースが混ざっているためコンパイルできず、古いプログラムを実行していると思われます。
オフトピック
NBK さんが書きました:mallocによる動的確保のコードは省略しました。
このまま実行すると、runtime errorになりました。
無駄な省略はしないでいただけるとわかりやすいです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: while内にあるif-elseの実行文が実行されない原因

#3

投稿記事 by みけCAT » 10年前

手元のコンパイラでhttp://ideone.com/kWXpVpのコードのテストをしましたが、

コード:

0
SUCCESS-DUMMY
と表示されました。

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種類
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

non
記事: 1097
登録日時: 13年前

Re: while内にあるif-elseの実行文が実行されない原因

#4

投稿記事 by non » 10年前

みけCATさんが言われてるように、実際に動かしているプログラムを載せてください。

コード:

typedef struct linkedlist{
        struct linkedlist *NEXT_ptr;
        struct linkedlist *PREVIEW_ptr;
        struct linkedlist *STATUS;
}list_t;
このSTATUSって?どんなリスト構造を考えているのでしょう。
何を作ろうとしているのか理解できません。
non

NBK

Re: while内にあるif-elseの実行文が実行されない原因

#5

投稿記事 by NBK » 10年前

みけ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;
 }

NBK

Re: while内にあるif-elseの実行文が実行されない原因

#6

投稿記事 by NBK » 10年前

nonさん、勝手に解決してしまいました・・・ごめんなさい・・・

> みけCATさんが言われてるように、実際に動かしているプログラムを載せてください。
実は、実際に動かしてるプログラムがすごい行数で説明するのもされるのも大変だと思ったので、
問題の箇所を抜き取るように小さい規模にして質問させていただきました。

> このSTATUSって?どんなリスト構造を考えているのでしょう。
> 何を作ろうとしているのか理解できません。

作ろうとしている構造は

HEAD <- -> DATA1 <- -> DATA2 <- -> DATA・・・<- -> END
というもので、HEADとENDもNEXT/PREVIEWポインタで繋がっています。

こういう循環リストを作ろうとしたとき、ループ条件をたとえば
while(HEAD->NEXT_ptr != NULL)
という式にしようと思ってましたが、循環になると無限ループに陥るので、
結局他に思い浮かばず、今はSTATUSというポインタにNULLポインタを入れることでループを終了させることにしました。

non
記事: 1097
登録日時: 13年前

Re: while内にあるif-elseの実行文が実行されない原因

#7

投稿記事 by non » 10年前

>list_t *HEAD = (list_t *)malloc(sizeof(list_t *));

これって不味くないですか?
non

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: while内にあるif-elseの実行文が実行されない原因

#8

投稿記事 by みけCAT » 10年前

include擬似命令も省略しないで欲しいです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

non
記事: 1097
登録日時: 13年前

Re: while内にあるif-elseの実行文が実行されない原因

#9

投稿記事 by non » 10年前

NBK さんが書きました:作ろうとしている構造は

HEAD <- -> DATA1 <- -> DATA2 <- -> DATA・・・<- -> END
というもので、HEADとENDもNEXT/PREVIEWポインタで繋がっています。
これは、わかります。私がお尋ねしたいのは、STATUSが
struct linkedlist *STATUS;
になっている理由です。
non

NBK

Re: while内にあるif-elseの実行文が実行されない原因

#10

投稿記事 by NBK » 10年前

nonさん

>list_t *HEAD = (list_t *)malloc(sizeof(list_t *));
おかしい理由は、引数にはバイト単位で指定しなきゃいけないからですか・・・?

> struct linkedlist *STATUS;
言われてみると、こうでなければいけない理由はありません・・・
でもベストな方法を言ってみろといわれると、わかりません。

NBK

Re: while内にあるif-elseの実行文が実行されない原因

#11

投稿記事 by NBK » 10年前

みけCAT さんが書きました:include擬似命令も省略しないで欲しいです。
はい、ちゃんと修正できたら、ちゃんとしたものをアップしたいと思います・・・

non
記事: 1097
登録日時: 13年前

Re: while内にあるif-elseの実行文が実行されない原因

#12

投稿記事 by non » 10年前

NBK さんが書きました: >list_t *HEAD = (list_t *)malloc(sizeof(list_t *));
おかしい理由は、引数にはバイト単位で指定しなきゃいけないからですか・・・?
確保したいバイト数はいくらなのでしょうか?
仮に、ポインタ変数が4バイトだとしたら、あなたが確保したいのは
何バイトですか?
NBK さんが書きました: > struct linkedlist *STATUS;
言われてみると、こうでなければいけない理由はありません・・・
でもベストな方法を言ってみろといわれると、わかりません。
間違っていると私は言っているわけではありません。どのような構造体を作りたいのでしょうか
と、お尋ねしているのです。このままでは、データを入れるメンバーがないのが気になっただけです。
テスト用ですからと言われれば、それで結構です。
non

NBK

Re: while内にあるif-elseの実行文が実行されない原因

#13

投稿記事 by NBK » 10年前

non さんが書きました: 確保したいバイト数はいくらなのでしょうか?
仮に、ポインタ変数が4バイトだとしたら、あなたが確保したいのは
何バイトですか?
確保したいのは1600バイトほど(=list_t型変数)です。
malloc(sizeof(list_t *)) はおかしいですね・・・
malloc(sizeof(list_t)) ですね・・・
non さんが書きました: 間違っていると私は言っているわけではありません。どのような構造体を作りたいのでしょうか
と、お尋ねしているのです。このままでは、データを入れるメンバーがないのが気になっただけです。
テスト用ですからと言われれば、それで結構です。
なるほど。はい、テスト用です。

NBK

Re: while内にあるif-elseの実行文が実行されない原因

#14

投稿記事 by NBK » 10年前

> 確保したいのは1600バイトほど(=list_t型変数)です。
> malloc(sizeof(list_t *)) はおかしいですね・・・
> malloc(sizeof(list_t)) ですね・・・

これウソです。ただのポインタ変数として使いたいです。

NBK

Re: while内にあるif-elseの実行文が実行されない原因

#15

投稿記事 by NBK » 10年前

>> 確保したいのは1600バイトほど(=list_t型変数)です。
>> malloc(sizeof(list_t *)) はおかしいですね・・・
>> malloc(sizeof(list_t)) ですね・・・

>これウソです。ただのポインタ変数として使いたいです。

全部ウソです(泣)すみません(泣)

HEADもENDも12バイトあれば事足ります。
NEXT/PREVIEW/STATUSの分なので。

non
記事: 1097
登録日時: 13年前

Re: while内にあるif-elseの実行文が実行されない原因

#16

投稿記事 by non » 10年前

NBK さんが書きました: malloc(sizeof(list_t)) ですね・・・
そうだと思います。
NBK さんが書きました: HEADもENDも12バイトあれば事足ります。
NEXT/PREVIEW/STATUSの分なので。
HEADやENDはポインタですから4バイトです。
HEADやENDが指している構造体が12バイトですね。
non

NBK

Re: while内にあるif-elseの実行文が実行されない原因

#17

投稿記事 by NBK » 10年前

non さんが書きました: HEADやENDはポインタですから4バイトです。
HEADやENDが指している構造体が12バイトですね。
なるほど。
つまりHEADでいえば、

HEAD = (list_t *)malloc(12);

ということですか?
HEADというポインタ変数に、確保された12バイト分のメモリ領域の先頭アドレスが代入される。
なんだか頭が混乱してきました・・・

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: while内にあるif-elseの実行文が実行されない原因

#18

投稿記事 by みけCAT » 10年前

ポインタのサイズは4バイトとは限りません。
HEAD = (list_t *)malloc(sizeof(list_t));
としてください。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

NBK

Re: while内にあるif-elseの実行文が実行されない原因

#19

投稿記事 by NBK » 10年前

みけCAT さんが書きました:ポインタのサイズは4バイトとは限りません。
HEAD = (list_t *)malloc(sizeof(list_t));
としてください。
僕の環境だと4バイトでした。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: while内にあるif-elseの実行文が実行されない原因

#20

投稿記事 by みけCAT » 10年前

NBK さんが書きました:
みけCAT さんが書きました:ポインタのサイズは4バイトとは限りません。
HEAD = (list_t *)malloc(sizeof(list_t));
としてください。
僕の環境だと4バイトでした。
compileonline</>comだと8バイトのようです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

NBK

Re: while内にあるif-elseの実行文が実行されない原因

#21

投稿記事 by NBK » 10年前

みけCAT さんが書きました: compileonline</>comだと8バイトのようです。
あ、CPUによって違うんですね・・・
じゃあバイトを数値で記述するのは良くないんですね。

non
記事: 1097
登録日時: 13年前

Re: while内にあるif-elseの実行文が実行されない原因

#22

投稿記事 by non » 10年前

そうですよ。だから最初に4バイトと仮定したらって書いてます。
non

NBK

Re: while内にあるif-elseの実行文が実行されない原因

#23

投稿記事 by NBK » 10年前

コードちゃんとしたのを載せます。
お二人に言われた部分を書き換えました。
ありがとうございました。

コード:

#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;
 }

NBK

Re: while内にあるif-elseの実行文が実行されない原因

#24

投稿記事 by NBK » 10年前

non さんが書きました:そうですよ。だから最初に4バイトと仮定したらって書いてます。
完全に読み飛ばしてました・・・
こんなアホに付き合ってくれてありがとうございました。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: while内にあるif-elseの実行文が実行されない原因

#25

投稿記事 by みけCAT » 10年前

NBK さんが書きました:
みけCAT さんが書きました: compileonline</>comだと8バイトのようです。
あ、CPUによって違うんですね・・・
じゃあバイトを数値で記述するのは良くないんですね。
利点はもう一点あります。
例えば

コード:

struct hoge {
    int value1[123];
    short value2[31];
    char value3[1023];
    char value4[14];
    int value5[11];
    double value6[634];
};
こんな構造体の要素を確保したいと思ったらどうしますか?
このサイズをいちいち手計算するのは大変ですし、アラインメントの問題もあります。
さらに、サイズを直接書く場合、構造体の中身を書き換えたら領域を確保している部分全てを書き換えないといけなくなります。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

NBK

Re: while内にあるif-elseの実行文が実行されない原因

#26

投稿記事 by NBK » 10年前

みけCAT さんが書きました: 利点はもう一点あります。
例えば

コード:

struct hoge {
    int value1[123];
    short value2[31];
    char value3[1023];
    char value4[14];
    int value5[11];
    double value6[634];
};
こんな構造体の要素を確保したいと思ったらどうしますか?
このサイズをいちいち手計算するのは大変ですし、アラインメントの問題もあります。
さらに、サイズを直接書く場合、構造体の中身を書き換えたら領域を確保している部分全てを書き換えないといけなくなります。
おお。確かにそうですね。
defineマクロもそうですが、形に置き換えることで汎用性が高まりますね。
ありがとうございます。

あの・・・アラインメントについて質問させてください。(たくさんお世話になって申し訳ないです。)
構造体をバイナリ形式でファイルに書き込むのは危険ですが、
その形式を使用しながらもバグを起こさない方法はどういうものがありますか?
#pragma packというマクロを見たことはありますが、使い方がさっぱりでした。
色々考えたりしたものの、解決できなくて・・・

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: while内にあるif-elseの実行文が実行されない原因

#27

投稿記事 by みけCAT » 10年前

その形式ってどの形式ですか?
バイナリ形式を使いたいなら、wavやbmpのように独自のファイルフォーマットを決めて書き込めばいいです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

NBK

Re: while内にあるif-elseの実行文が実行されない原因

#28

投稿記事 by NBK » 10年前

みけCAT さんが書きました:その形式ってどの形式ですか?
バイナリ形式を使いたいなら、wavやbmpのように独自のファイルフォーマットを決めて書き込めばいいです。
あ、なるほど。ありがとうございました。

閉鎖

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