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

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

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

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

3185閲覧

c++ メモリの動的確保

fgfnabwym

総合スコア78

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2015/07/20 13:13

次のプログラムのメモリを動的に確保したいのですが、思うようにうまくいきません。

newとdeleteを使わず、静的にメモリを確保すると、プッシュもポップも上手くいきます。
しかし、newとdeleteを使うとプッシュは出来るのですが、ポップの時に格納した値が取り出されず、文字化けされたように値が取り出されます。

動的にメモリを確保する方法を教えて下さい。

c++

1#include <iostream> 2#include <vector> 3using namespace std; 4 5#define SIZE 10 6 7// 汎用stackクラスを作成する 8template <class StackType> class stack { 9 StackType stck[SIZE][2]; // スタックの領域を確保する 10 int tos; // スタックの先頭を索引 11public: 12 void init() { tos = 0; } // スタックを初期化する 13 void push(StackType ob, StackType ob2); // スタックにオブジェクトをプッシュする 14 StackType pop(StackType &ob2); // スタックにオブジェクトをポップする 15}; 16 17// オブジェクトをプッシュする 18template <class StackType> 19void stack<StackType>::push(StackType ob, StackType ob2) 20{ 21 /* new */ 22 // StackType*の配列を動的生成 23 StackType **stck = new StackType*[SIZE]; 24 // 配列の各要素でStackTypeの配列を動的生成 25 stck[tos] = new StackType[2]; 26 27 if (tos == SIZE) { 28 cout << "スタックは一杯です\n"; 29 return; 30 } 31 stck[tos][0] = ob; 32cout << "stck[" << tos << "][0]" << stck[tos][0] << '\n'; 33 stck[tos][1] = ob2; 34cout << "stck[" << tos << "][1]" << stck[tos][1] << '\n'; 35cout << "tosの値+前" << tos << '\n'; 36 tos++; 37cout << "tosの値+後" << tos << '\n'; 38 /* delete */ 39 // 各要素を先にdelete 40 delete[] stck[tos]; 41 stck[tos] = 0; 42 delete[] stck; 43 stck = 0; 44} 45 46// オブジェクトをポップする 47template <class StackType> 48StackType stack<StackType>::pop(StackType &ob2) 49{ 50 51 if (tos == 0) { 52 cout << "スタックは空です\n"; 53 return 0; // スタックが空の場合はヌルを返す 54 } 55 56cout << "tosの値-前" << tos << '\n'; 57 tos--; 58cout << "tosの値-後" << tos << '\n'; 59 ob2 = stck[tos][1]; 60cout << "stck[" << tos << "][0]" << stck[tos][0] << '\n'; 61cout << "stck[" << tos << "][1]" << stck[tos][1] << '\n'; 62 return stck[tos][0]; 63 64} 65 66int main() 67{ 68 // 文字スタックの動作を確認する 69 stack<char> s1; // スタックを作成する 70 int i; 71 char ch; 72 73 // スタックを初期化する 74 s1.init(); 75 s1.push('a', 'm'); 76 s1.push('e', 'q'); 77 s1.push('q', 'p'); 78 79cout << '\n'; 80 for (i = 0;i < 3;i++) { 81 cout << "s1をポップする:" << s1.pop(ch) ; 82 cout << ' ' << ch << '\n'; 83 } 84 return 0; 85} 86

実行

stck[0][0]a stck[0][1]m tosの値+前0 tosの値+後1 stck[1][0]e stck[1][1]q tosの値+前1 tosの値+後2 stck[2][0]q stck[2][1]p tosの値+前2 tosの値+後3 tosの値-前3 tosの値-後2 stck[2][0]6 stck[2][1] s1をポップする:6 tosの値-前2 tosの値-後1 stck[1][0] stck[1][1] s1をポップする: tosの値-前1 tosの値-後0 stck[0][0] stck[0][1]・ s1をポップする: ・

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

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

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

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

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

guest

回答2

0

this->stckをコンストラクタでnewして、デストラクタでdeleteする必要があるかと思います。
今のコードですとpush()でローカル変数のstckをnewして最後にdeleteで破棄しているので、
何も操作していないのと同じ状態です。
対してpop()はthis->stckを見に行ってしまっていて、ここはここでメモリを確保していますが、
0埋めしているわけではないため、入っているのはゴミデータが返ってきているのだと思います。

投稿2015/07/20 13:29

raccy

総合スコア21733

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

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

fgfnabwym

2015/07/20 14:08

raccyさんありがとうございます。直してみます。
guest

0

ベストアンサー

pushでnewしてpopでdeleteするんだね
ただ、その時確保した地点へのポインタが必要になる

そう考えると動的に確保するためのデータ構造が全く見えないんだ

ごめんスマホで感覚しか教えられないしプログラム雑になるから詳しくはリストのデータ構造の本で調べて

構造体{
何か型
構造体ポインタ
}

こんな感じに書いてクラスのメンバ?にヘッダとして構造体ポインタを持たせて見失わないようにしたら大丈夫
あとは、減らしていって空になった時エラーが出たり変なことが起きなければ大丈夫

もし、配列構造でデータを扱おうとしてたらinitで適当に確保してpopで不足時に余力がある程度に確保してコピーして廃棄して新しく値を入れる手順になるただこれはアルゴリズムとして複雑さが増すし実行速度も不足した地点で最悪になるは

投稿2015/07/20 21:00

編集2015/07/21 07:49
a-tiny

総合スコア25

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

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

a-tiny

2015/07/21 15:19 編集

動的確保に関する質問で 質問者は動的確保は出来るが それに向いているデータ構造を理解していないと判断できたので スタックに関する質問でしたがlistを教えました 質問者は配列を用いてリストを表現していたようですがそれでは配列を大規模に確保コピー開放を行うため時間がかかると判断したのでの控えた回答にとどめました もしそれについてSTL内のvectorに詳しい方がいてマイナスに転じているのなら納得がつきますが
fgfnabwym

2015/07/21 11:41

a-tinyさん、回答ありがとうございました。 助かりました。また、私の力に合わせ回答を書いてくださり、うれしかったです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問