c++ メモリの動的確保
解決済
回答 2
投稿
- 評価
- クリップ 0
- VIEW 2,276
newとdeleteを使わず、静的にメモリを確保すると、プッシュもポップも上手くいきます。
しかし、newとdeleteを使うとプッシュは出来るのですが、ポップの時に格納した値が取り出されず、文字化けされたように値が取り出されます。
動的にメモリを確保する方法を教えて下さい。
#include <iostream>
#include <vector>
using namespace std;
#define SIZE 10
// 汎用stackクラスを作成する
template <class StackType> class stack {
StackType stck[SIZE][2]; // スタックの領域を確保する
int tos; // スタックの先頭を索引
public:
void init() { tos = 0; } // スタックを初期化する
void push(StackType ob, StackType ob2); // スタックにオブジェクトをプッシュする
StackType pop(StackType &ob2); // スタックにオブジェクトをポップする
};
// オブジェクトをプッシュする
template <class StackType>
void stack<StackType>::push(StackType ob, StackType ob2)
{
/* new */
// StackType*の配列を動的生成
StackType **stck = new StackType*[SIZE];
// 配列の各要素でStackTypeの配列を動的生成
stck[tos] = new StackType[2];
if (tos == SIZE) {
cout << "スタックは一杯です\n";
return;
}
stck[tos][0] = ob;
cout << "stck[" << tos << "][0]" << stck[tos][0] << '\n';
stck[tos][1] = ob2;
cout << "stck[" << tos << "][1]" << stck[tos][1] << '\n';
cout << "tosの値+前" << tos << '\n';
tos++;
cout << "tosの値+後" << tos << '\n';
/* delete */
// 各要素を先にdelete
delete[] stck[tos];
stck[tos] = 0;
delete[] stck;
stck = 0;
}
// オブジェクトをポップする
template <class StackType>
StackType stack<StackType>::pop(StackType &ob2)
{
if (tos == 0) {
cout << "スタックは空です\n";
return 0; // スタックが空の場合はヌルを返す
}
cout << "tosの値-前" << tos << '\n';
tos--;
cout << "tosの値-後" << tos << '\n';
ob2 = stck[tos][1];
cout << "stck[" << tos << "][0]" << stck[tos][0] << '\n';
cout << "stck[" << tos << "][1]" << stck[tos][1] << '\n';
return stck[tos][0];
}
int main()
{
// 文字スタックの動作を確認する
stack<char> s1; // スタックを作成する
int i;
char ch;
// スタックを初期化する
s1.init();
s1.push('a', 'm');
s1.push('e', 'q');
s1.push('q', 'p');
cout << '\n';
for (i = 0;i < 3;i++) {
cout << "s1をポップする:" << s1.pop(ch) ;
cout << ' ' << ch << '\n';
}
return 0;
}
実行
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をポップする: ・
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+1
今のコードですとpush()でローカル変数のstckをnewして最後にdeleteで破棄しているので、
何も操作していないのと同じ状態です。
対してpop()はthis->stckを見に行ってしまっていて、ここはここでメモリを確保していますが、
0埋めしているわけではないため、入っているのはゴミデータが返ってきているのだと思います。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
checkベストアンサー
-1
ただ、その時確保した地点へのポインタが必要になる
そう考えると動的に確保するためのデータ構造が全く見えないんだ
ごめんスマホで感覚しか教えられないしプログラム雑になるから詳しくはリストのデータ構造の本で調べて
構造体{
何か型
構造体ポインタ
}
こんな感じに書いてクラスのメンバ?にヘッダとして構造体ポインタを持たせて見失わないようにしたら大丈夫
あとは、減らしていって空になった時エラーが出たり変なことが起きなければ大丈夫
もし、配列構造でデータを扱おうとしてたらinitで適当に確保してpopで不足時に余力がある程度に確保してコピーして廃棄して新しく値を入れる手順になるただこれはアルゴリズムとして複雑さが増すし実行速度も不足した地点で最悪になるは
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.21%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2015/07/20 23:08