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

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

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

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

Q&A

解決済

3回答

3944閲覧

c++におけるコンテナの使い方

eTakahiro

総合スコア10

C++

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

0グッド

0クリップ

投稿2016/11/11 08:53

編集2016/11/11 09:03

ベクトルコンテナに整数を格納していき、最初と最後の5つを表示した後に昇順にソートしてまた最初と最後の5つを表示したいのですが、実行時にエラーが出てしまいました。
コンテナの概念がまだよくわかっていないので、教えていただけたら嬉しいです。

cpp

1#include<iostream> 2#include<vector> 3using namespace std; 4 5void sort_input(vector<int> *a){ 6 vector<int>::size_type t, u; 7 vector<int> temp; 8 for (t = 0; t < a->size(); t++){ 9 for (u = a->size() - 1; u > t - 1; u++){ 10 if (a[u] < a[u - 1]){ 11 temp = a[u]; 12 a[u] = a[u - 1]; 13 a[u - 1] = temp; 14 } 15 } 16 } 17} 18 19int main(void) 20{ 21 int input; 22 vector <int> iv; 23 do { 24 cin >> input; 25 iv.push_back(input); 26 } while (input > 0); 27 vector<int>::size_type s; 28 cout << "\n\n"; 29 for (s = 0; s <5; s++) { 30 cout << iv[s] << endl; 31 } 32 cout << "\n\n"; 33 for (s = iv.size() - 5; s < iv.size(); s++){ 34 cout << iv[s] << endl; 35 } 36 cout << "\n\n"; 37 sort_input(&iv); 38 for (s = 0; s <5; s++) { 39 cout << iv[s] << endl; 40 } 41 cout << "\n\n"; 42 for (s = iv.size() - 5; s < iv.size(); s++){ 43 cout << iv[s] << endl; 44 } 45 46 return 0; 47

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

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

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

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

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

guest

回答3

0

void sort_input(vector<int> *a){

まず、sort_input関数へのvectorオブジェクトの渡し方に誤りがあります。ポインタ渡しではなく参照で渡してください。ポインタで渡しているため、まったく見当違いの処理になってしまい、アクセス違反が発生しているものと思われます。
参照渡しは&aと書きます。参照渡しした変数は通常の変数と同様a.size()のようにピリオドでメンバを指定してください。
C++では、ポインタ渡しでなければ困る理由がない限り、参照渡しにしてください。

変数tempvectorではなく、配列の要素であるint型で定義してください(引数をポインタ渡しにしているためおかしなことになっています)。

それと、バブルソートだと思いますが、ソートのアルゴリズムが正しく実装されていません。

for (t = 0; t < a->size(); t++){

二つの値を比較しながらループを進めるため、外側のループは、最後の要素の1個手前になるようにします。t < a.size() - 1としてください。

for(u = a->size() - 1; u > t - 1; u++)

ループの中の処理からすると、後ろから進めてutの一つ後ろになるまでループさせたいので、終了条件に- 1は不要でu > tとしてください。そして、前方向にインデックスを進めるので`u--'としないといけません。

投稿2016/11/11 09:41

編集2016/11/11 09:47
catsforepaw

総合スコア5938

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

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

eTakahiro

2016/11/11 10:00

ポインタ渡しだとよくないというのはコンテナだからなのですか?構造体の時は問題なかったのですが、そういうのもやはりc++では参照渡しを使ったほうがいいのですか?? ソートのところもだいぶ間違ってましたね汗 ちゃんとやろうと思います。ありがとうございます。
catsforepaw

2016/11/11 10:20

ポインタ渡しにすべきでないのは、コンテナに限らず、intやdoubleなどの組み込み型も含めた全てのオブジェクトです。構造体の時に問題がなかったのは、たまたまです。今回の問題もポインタに起因していますが、それはクラスだからというものではありません。 このように、ポインタにするとそれにまつわる問題に対処する必要が出てきて、本来の処理とは違うところにコストを掛けることになりますから、本当にポインタでなければ困るような特別な事情がない限りは参照渡しにしてください。 それに、メンバ変数・関数を呼ぶ際の書き方が通常の変数と異なるのは統一感がなくて見栄えが悪いです。
eTakahiro

2016/11/11 10:28

ポインタがやっかいなものだとは知りませんでした。確かに見栄えも悪いですね。 これからは参照渡しを使っていこうと思います。ありがとうございました。
guest

0

ベストアンサー

コンテナの概念がまだよくわかっていないので、教えていただけたら嬉しいです。

C++標準ライブラリが提供するコンテナは「実行時にその要素を追加/削除できるデータ構造」です。

その中でも一番利用頻度が高いのがstd::vectorでしょう。こちらは「実行時に要素を追加/削除できる可変長配列」と捉えればOKです。

直接的な問題は、void sort_input(vector<int>* a)関数内でa[n]とアクセスした場合、「vectorのn番目の要素」ではなく、「"vectorの配列"があったとして、そのn番目のvector」になってしまいます。そのようなデータ領域は存在しないため、プログラムは実行時にクラッシュします。

修正方法としては、A)関数引数を参照型vector<int>& aとするか、B)要素アクセス時にa->at(n)に変更する必要があります。C++プログラムの設計としてはA)の方が自然だと思います。

投稿2016/11/11 09:07

編集2016/11/11 09:19
yohhoy

総合スコア6191

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

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

eTakahiro

2016/11/11 09:21

なるほど... ありがとうございます。やってみます。
eTakahiro

2016/11/11 09:44

void sort_input(vector<int> &a){ vector<int>::size_type t, u; int temp; for (t = 0; t < a.size(); t++){ for (u = a.size() - 1; u > t - 1; u--){ if (a[u] > a[u - 1]){ temp = a[u]; a[u] = a[u - 1]; a[u - 1] = temp; } } } } できました! tempもint型にしました。先ほどはなぜtempをint型にしたらビルド時に型が違うとエラーが出たのか謎です。
yohhoy

2016/11/11 14:06

参考までに: (学習目的でなければ)C++標準ライブラリで std::sort 関数が提供されますから、通常のソート処理ではそちらを使った方が良いですね。
guest

0

エラー内容が書かれていないので想像ですが、
このコードだと入力回数が5回未満だと、下記のコードでマイナスの値が添字に使われてしまいます。
(iv[-1] みたいな)

c++

1for (s = iv.size() - 5; s < iv.size(); s++){ 2 cout << iv[s] << endl; 3}

投稿2016/11/11 09:03

編集2016/11/11 09:06
ishi9

総合スコア1294

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

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

eTakahiro

2016/11/11 09:11

エラーというか動作を停止してしまいます。ソート関数の前までは表示されていました。 確かに5回未満だと要素がマイナスになってしまいますね。。 終了条件はwhile(input>0)なのでたぶん大丈夫ではないですか??
ishi9

2016/11/11 09:16

あぁ多分これですかね for (u = a->size() - 1; u > t - 1; u++){ 多分これ「u--」ですよね。 あんまり頭働かせてないので自信ないですが
eTakahiro

2016/11/11 09:23

あ、確かにそうでした。すいませんm(_ _)m
ishi9

2016/11/11 09:33 編集

本当にすいません、頭働かせてないにも程がありました。(u--にしろとか完全に見当違いですので忘れてください) 今まで全然見当違いの事を言っていました。 yohhoy様の言っている事が全部ですね。 a[u] ← これはint型をさしています。 a[u] = 1; // これなら入る でもコードよく見たら a[u] = temp // tempはvector<int>型 これは入りません vector<int> temp; ↓ int temp; に書き直してください。
eTakahiro

2016/11/11 09:45

int型にしたらできました!ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問