C++ std::stack ポインタ

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

C++ std::stack ポインタ

#1

投稿記事 by C言語中級 » 12年前

VC++2008
windows7
corei5
などの環境でスタックを用いたプログラミングをしているのですが,バグが解決できず困っています.
以下に実際のプログラムを模したプログラムを載せました.

コード:

class Pos{
private:
	int x, y;
public:
	Pos(int x, int y){
		this->x = x; 
		this->y = y; 
	}
	Pos(){}
};
void test(){
             /* メモリ確保 */
             int seeds = 2;
   	int* seedx = (int*)malloc(sizeof(int)*seeds);
	int* seedy = (int*)malloc(sizeof(int)*seeds);
             std::stack<Pos> *st = (std::stack<Pos>*)malloc(sizeof(std::stack<Pos>) * seeds);
             /* 初期化 */
             	seedx[0] = 0;
	seedy[0] = 0;
             	seedx[1] = 232;
	seedy[1] = 146;
             	Pos p0(seedx[0],seedy[0]);
	Pos p1(seedx[1],seedy[1]);
             	st[0].push(p0);
	st[1].push(p1);              
             //又は
             //st[0].push(Pos(seedx[0],seedy[0]));
             //st[1].push(Pos(seedx[1],seedy[1]));
              //どっちにしろtopするとエラーになります.
             Pos p = st[0].top();//ここでプログラムが強制終了              
}
このようにstackを配列にしたプログラム(これが目的)を作ったのですが,コンパイルは通りますが,
実行時に
~.exeは動作を終了しました.と表示されてしまいます.

puts("")文などで古典的なデバックをしたところ,top()の前で処理が止まっていることが判明しましたが,原因が分かりません.
分かる方いましたらお願いします.

C言語中級

Re: C++ std::stack ポインタ

#2

投稿記事 by C言語中級 » 12年前

ソースコードが改行されてないので,もう一度同じものを載せます.

コード:

class Pos{
private:
	int x, y;
public:
	Pos(int x, int y){
		this->x = x; 
		this->y = y; 
	}
	Pos(){}
};
void test(){
	/* メモリ確保 */
	int seeds = 2;
	int* seedx = (int*)malloc(sizeof(int)*seeds);
	int* seedy = (int*)malloc(sizeof(int)*seeds);
	std::stack<Pos> *st = (std::stack<Pos>*)malloc(sizeof(std::stack<Pos>) * seeds);
	/* 初期化 */
	seedx[0] = 0;
	seedy[0] = 0;
	seedx[1] = 232;
	seedy[1] = 146;
	Pos p0(seedx[0],seedy[0]);
	Pos p1(seedx[1],seedy[1]);
	st[0].push(p0);
	st[1].push(p1);              
	//又は
	//st[0].push(Pos(seedx[0],seedy[0]));
	//st[1].push(Pos(seedx[1],seedy[1]));
	//どっちにしろtopするとエラーになります.
	Pos p = st[0].top();//ここでプログラムが強制終了              
}

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: C++ std::stack ポインタ

#3

投稿記事 by h2so5 » 12年前

C++のクラスのインスタンスの動的確保にはnewを使います。mallocを使ってはいけません。
mallocではコンストラクタが呼ばれないため、想定外の動作を引き起こします。

せっかくC++を使っているのだから、動的配列にはvectorをお勧めします。

C言語中級

Re: C++ std::stack ポインタ

#4

投稿記事 by C言語中級 » 12年前

h2so5 さんが書きました:C++のクラスのインスタンスの動的確保にはnewを使います。mallocを使ってはいけません。
mallocではコンストラクタが呼ばれないため、想定外の動作を引き起こします。

せっかくC++を使っているのだから、動的配列にはvectorをお勧めします。

返信有難う御座います. 非常に助かりました.
std::stack<Pos> *st = (std::stack<Pos>*)malloc(sizeof(std::stack<Pos>) *seeds);

std::stack<Pos> *st = new std::stack<Pos>();
に書き換えた所,少しましになったのですが,
ここには書いてないこの後のスタックのループ処理で,以下模したもの(要点のみで簡略化してます.).

コード:

for(int i=0;i<seeds;i++){
    while(!(st[i].empty())){//ある配列番号のスタックが空でない間繰り返す
        Pos p = st[i].top();//取り出す
        st[i].pop();//取り出したものを削除        
        if(条件を満たした場合はプッシュ)st[i].push(ある座標x,ある座標y);
    }
}
    
これで何十回目かのpush時に先ほどと同じエラーがでます.

vectorの使用は考慮したのですが,リファレンスのようなものを見たところ,
1先頭に入れる
2先頭から取り出す
3先頭の要素を削除
この3つがそろってないように見えたので,やめました.

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: C++ std::stack ポインタ

#5

投稿記事 by h2so5 » 12年前

C言語中級 さんが書きました: std::stack<Pos> *st = new std::stack<Pos>();
に書き換えた所,少しましになったのですが,
ここには書いてないこの後のスタックのループ処理で,以下模したもの(要点のみで簡略化してます.).

コード:

for(int i=0;i<seeds;i++){
    while(!(st[i].empty())){//ある配列番号のスタックが空でない間繰り返す
        Pos p = st[i].top();//取り出す
        st[i].pop();//取り出したものを削除        
        if(条件を満たした場合はプッシュ)st[i].push(ある座標x,ある座標y);
    }
}
    
これで何十回目かのpush時に先ほどと同じエラーがでます.
stackが1つしか確保されていないので、st[1]が範囲外アクセスになります。
C言語中級 さんが書きました: vectorの使用は考慮したのですが,リファレンスのようなものを見たところ,
1先頭に入れる
2先頭から取り出す
3先頭の要素を削除
この3つがそろってないように見えたので,やめました.
先頭への挿入操作がしたい場合は、std::list かstd::dequeを使ってください
vectorでも先頭の要素へのアクセスは vector::frontで可能です

C言語中級

Re: C++ std::stack ポインタ

#6

投稿記事 by C言語中級 » 12年前

h2so5 さんが書きました:
C言語中級 さんが書きました: std::stack<Pos> *st = new std::stack<Pos>();
に書き換えた所,少しましになったのですが,
ここには書いてないこの後のスタックのループ処理で,以下模したもの(要点のみで簡略化してます.).

コード:

for(int i=0;i<seeds;i++){
    while(!(st[i].empty())){//ある配列番号のスタックが空でない間繰り返す
        Pos p = st[i].top();//取り出す
        st[i].pop();//取り出したものを削除        
        if(条件を満たした場合はプッシュ)st[i].push(ある座標x,ある座標y);
    }
}
    
これで何十回目かのpush時に先ほどと同じエラーがでます.
stackが1つしか確保されていないので、st[1]が範囲外アクセスになります。
C言語中級 さんが書きました: vectorの使用は考慮したのですが,リファレンスのようなものを見たところ,
1先頭に入れる
2先頭から取り出す
3先頭の要素を削除
この3つがそろってないように見えたので,やめました.
先頭への挿入操作がしたい場合は、std::list かstd::dequeを使ってください
vectorでも先頭の要素へのアクセスは vector::frontで可能です
ご指摘有難う御座います.C++言語はあまり分かっていないので,助かりました.
std::stack<Pos> *st = new std::stack<Pos>();

std::stack<Pos> *st = new std::stack<Pos>[seeds];
に変更したところ.
完全に動きました.
これにて解決とします.
listやdepueなども視野に入れておきます.

閉鎖

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