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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

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

Q&A

解決済

7回答

4838閲覧

[C++] 配列の使い分け?について

yama_da

総合スコア73

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

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

0グッド

0クリップ

投稿2017/03/13 05:32

編集2017/03/13 05:38

こんにちは。

あらかじめ配列の要素数が分かっているわけではなく、コンストラクタの引数によって要素数が決定し、それ以降要素数は変化しないような場合は、std:vectorを固定長配列のように扱うか、int*のようにポインタをメンバに持ち、newで動的に確保するのとどちらが良いのでしょうか?

後者の例は以下のような感じです。

C++

1class Hoge 2{ 3 int* array; 4 5 Hoge(size_t size) 6 { 7 array=new int[size]; 8 } 9};

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

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

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

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

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

guest

回答7

0

ベストアンサー

少々乱暴な意見を言えばvectorを使っておいた方がよいのではないか、と思います。

一般的に用意されているライブラリーの定義は自分でやるよりは面倒が少なくバグがないだろうとの考えに基づくならvectorやその他のライブラリーから選択するのはよいことだと思います。そのようなライブラリーでは「目的に対して不十分」という不満があるときに自前の実装を考えることもあるでしょう。

実装には様々な要件がありますね?例えば「柔軟性」「メモリー効率」「アクセス効率」「安全性」等々が考えられます。配列の大きさが固定か可変かは柔軟性にあたるもので重要なファクターではありますが、それだけではどれがよいかを選べるほどの十分な条件にならないと思います。

そのような判断をするにはvectorなどのライブラリーの特性を理解し、自分のコードが要求する目的を考えたうえでその特定がマッチするかどうかを判断することが大事だと思います。

おそらくはC++の経験豊富なプログラマーの方ならここに書ききれないぐらいの「列を定義するときの判断基準や用意されているクラスの特性の違い」を語れるのではないかと想像します。自分は素人に近いレベルなのでそんなことは語れませんが、「自分で定義するかvectorその他のクラスを使うか」迷ったときがチャンスととらえvectorが持つ特性を色々調べると思います。そういうことって大事だと思います。

さて最初にvectorを使っておいた方がよいと意見を言いました。それは自前実装よりは安全・手軽であろうこと、vectorの特徴を使ってみて知ることは意義があると思えることから「判断に迷うなら経験を積むのがよいのではないか」と思った程度の理由です。逆に「自前で定義することで実装詳細の経験を積むこともできる」という意見もあるかも知れませんね。

投稿2017/03/13 07:00

編集2017/03/13 08:49
KSwordOfHaste

総合スコア18394

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

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

0

僕ならvectorを選びます。
やっぱり可変長 とか
やっぱりlist とか、
実装の変更時にre-workが少ないので。

※ 未来永劫固定長ならお好きな方を。

[追記] vector(等標準コンテナ)ならデストラクタで明示的に delete[] せんでも勝手に後始末してくれますな。

投稿2017/03/13 07:07

編集2017/03/13 07:12
episteme

総合スコア16614

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

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

yama_da

2017/03/14 19:18

回答ありがとうございます。 >実装の変更時にre-workが少ないので そうですね、特にint*にする理由もないので、後々のことも考えてvectorにしようと思います。 ありがとうございました!
guest

0

こんにちは。

メモリ消費はstd:vector<>使っても大差ない場合が多いですので、int*を使った方が良い理由が特にない限り「車輪を再発明する」よりstd::vector<>を使った方が良いと思います。

ところで、後者はデストラクタも必要ですね。(単なる省略と思いますが、念のため。)

投稿2017/03/13 07:05

Chironian

総合スコア23272

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

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

yama_da

2017/03/14 19:16

回答ありがとうございます。 >メモリ消費はstd:vector<>使っても大差ない場合が多いですので そうなんですか!直感的にvector>固定長配列 だと思っていました。 int*を使う理由が特別ある訳では無いので、vectorを使うことにします。ありがとうございました!
Chironian

2017/03/15 00:52

vectorは要素数を記録する領域がint*より多いです。でも高々4 or 8バイトですし、int*でも要素数を記録したくなることも結構多いです。
guest

0

std::vectorに一票。

理由は、他の方々もおっしゃっているように、"すでに実装されているから" です。

int型ポインタでもいいですが、

たとえば for文でループさせるために、

最大要素数を取得しますよね。

intポインタの場合、sizeofマクロとかで割り出さないといけませんが、

std::vectorの場合、vector::sizeメンバ関数で 取得できます。

たとえば、

C++

1vector<int> stock; 2 3// ここでデータをセット 4 5int max = (int)stock.size();

のように。

あるいはイテレータ ( iterator ) を使って、

C++

1vector<int> stock; 2 3// ここでデータをセット 4 5vector<int>::iterator it; 6 7for( it = stock.begin(); it != stock.end(); it++ ){ 8 // 何らかの処理 9}

のようにできますし。

投稿2017/03/14 03:40

BeatStar

総合スコア4958

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

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

HogeAnimalLover

2017/03/14 12:25

sizeofマクロで要素数を取り出せるのは固定長(コンパイル時に決定している場合)に限ります。また、要素数もクラスのフィールド値としておけばいいので、この例は不適だと思います。
yama_da

2017/03/14 19:24

回答ありがとうございます。 >理由は、他の方々もおっしゃっているように、"すでに実装されているから" やっぱりそうなんですね。 vectorにしようと思います。ありがとうございました!
BeatStar

2017/03/17 02:04

HogeAnimalLoverさんのおっしゃる通りですね。 私は趣味でやっているので細かい細かいことはわからないので...
guest

0

特別な理由がない限りvector。自前で実装するのはバグと保守性低下のもと。
特別な理由とは、stlが使用できない場合(組み込み系など)、vectorの使用では速度が確保できない、ROMに入らない、など、非常に限られたもののこと。一定のメモリプールから確保するような場合でも、アロケータが指定できるので、vectorを使わない理由にはならない。

投稿2017/03/13 15:45

majiponi

総合スコア1720

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

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

yama_da

2017/03/14 19:22

回答ありがとうございます。 >自前で実装するのはバグと保守性低下のもと。 そうですね、すでに標準で実装されてる物があるならそれを使った方が早いし安全ですね。vectorでいくことにしました。ありがとうございました!
guest

0

皆さんと同じで、コンパイル時に決まっていないのならvectorですね。
new/deleteは極力使わないほうがバグは出にくくなります。特に、メモリリークは探すのが大変な場合が有ります。

投稿2017/03/14 09:31

PineMatsu

総合スコア3579

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

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

0

コンパイル時に要素数が確定していないだけで、「コンストラクタからデストラクタの間において要素数の変動が生じえない」というのが真ならば、int*型でも十分だと私は思います。まあ実際は「仕様変更」なんてザラに起こり得ることですがね。

まあせっかく作るのなら、要素数もフィールドで保持しておいて、アクセス時にエラーチェックするくらいのことをしても良いと思います。サンプル↓ 動作未確認

C++

1class Hoge 2{ 3 int* array; 4 int size; 5public: 6 int getN(int n)const{ 7 if(0 <= n && n < size){ 8 return array[n]; 9 } 10 //エラー処理を書く 11 } 12 void setN(int n, int val){ 13 if(0 <= n && n < size){ 14 array[n] = val; 15 }else{ 16 //エラー処理を書く 17 } 18 } 19 Hoge(size_t size0):size(size0), array(new int[size0]) 20 { 21 } 22 ~Hoge() 23 { 24 delete[] array; 25 array = NULL;//不要だけど念のため 26 } 27};

投稿2017/03/14 12:35

HogeAnimalLover

総合スコア4830

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

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

yama_da

2017/03/14 19:28

回答ありがとうございます。 後々のことも考えて、vectorで行こうと思います。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問