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

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

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

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

Q&A

解決済

2回答

895閲覧

ポインタvector型への変換

ianaka3

総合スコア24

C++

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

0グッド

0クリップ

投稿2023/03/18 06:14

C++ ポインタvector配列への詰め替え

vector型から ポインタvector型への変換を行いたいです。

  • const std::vector<T>&からconst std::vector<T*>&への変換

前提

C++の使用歴が浅く、不勉強であることは承知しております。
社内でC++がわかる人もおらず、前任者もいないため困り果てています。

社内の遺産的なコードに手を入れている関係で大きく作り直すことは不可能であり、
今回、このような対応をすることとなりました。

発生している問題・エラーメッセージ

const std::vector<T>&から、const std::vector<T*>&への変換方法がわからない。

該当のソースコード

C++

1 2void ClassA::MethodA(const std::vector<T> & arg1) 3{ 4 const std::vector<T*> arg2; 5 /* 6 ここで、arg1からarg2への詰め替えを行いたい。 7   この詰め替え方法がわからないです。 8 */ 9 10  // 詰め替えたarg2をMethodBの引数として使用したい。 11 MethodB(arg2); 12} 13 14void ClassA::MethodB(const std::vector<T*>& arg3) 15{ 16 //引数arg3を使用して処理を行う 17}

試したこと

arg2に対して、push_backを行うときにnewなどを行いましたが、メモリリークを引き起こしてしまい、
できませんでした。
何をどうすれば、新しいvectorに詰め替えることができるのか見当もつかず困り果てています。

補足情報(FW/ツールのバージョンなど)

ツールはvisual studio 2012、言語はC++です。

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

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

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

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

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

ianaka3

2023/03/19 00:24

すいません。 私の書き方がいけなかったのですが、vector<T>のTが独自クラスの場合、どうすれば良いのか教えて頂けると助かります。
episteme

2023/03/19 04:46 編集

独自クラスの場合、何か問題がありますか?
guest

回答2

0

すでに解決方法は出たようですので、補足的に解説をします。

vector は実質的に内部に配列を持っており、そこに要素を格納するという構造です。

質問中の

push_back を行うときに new などを行いましたが

というのはおそらく以下のような要領でしょうが、個々の要素の管理は vector は行わないので寿命が尽きる前に個々に delete をしないと回収されずにメモリリークとなってしまいます。

cpp

1#include <iostream> 2#include <vector> 3 4int main() { 5 std::vector<int> src = {1, 2, 3}; 6 std::vector<int*> dst; 7 8 // int -> int* 9 for (int& item : src) { 10 // あらたにメモリを割りあてると…… 11 dst.push_back(new int(item)); 12 } 13 14 for (int* item : dst) { 15 std::cout << (void*)item << " " << *item << std::endl; 16 } 17 18 // 解放する必要がある 19 for (int* item : dst) { 20 delete item; 21 } 22}

図で言えばこういう構造ですが……
イメージ説明
詰め替え後の vector の寿命が尽きても個々の要素の管理はまた別だということです。
イメージ説明

episteme さんが提示する方法は元の要素をそのまま指すというものです。
イメージ説明
質問文に書かれている状況だとおそらくこれで良いとは思うのですが、 vector は状況によって内部で管理する配列の再配置をすることがあります。 詳細な条件はここでは述べませんがたとえば要素をひとつ追加するというだけでも再配置が起こる可能性があります。
イメージ説明
もしも再配置が起こってしまうと再配置が起こる前の場所を指しているポインタは全て無効になってしまいます。 つまり再配置が起こらないように配慮する必要があり、よく理解できていないならポインタの vector を使っている間は元の配列には全く触れないのが無難です。

投稿2023/03/19 01:26

SaitoAtsushi

総合スコア5446

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

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

0

ベストアンサー

C++

1#include <iostream> 2#include <vector> 3 4int main() { 5 std::vector<int> src = { 1, 2, 3 }; 6 std::vector<int*> dst; 7 8 // int -> int* 9 for ( int& item : src ) { 10 dst.push_back(&item); 11 } 12 13 // できたかな? 14 for ( int* item : dst ) { 15 std::cout << (void*)item << " " << *item << std::endl; 16 } 17}

[追記]

vector<T>のTが独自クラスの場合、どうすれば良いのか教えて頂けると助かります。

同じです。

C++

1#include <iostream> 2#include <vector> 3 4class foo { 5 int value_; 6public: 7 foo(int v=0) : value_(v) {} 8 int value() const { return value_; } 9}; 10 11int main() { 12 std::vector<foo> src = { 1, 2, 3 }; 13 std::vector<foo*> dst; 14 15 // foo -> foo* 16 for ( foo& item : src ) { 17 dst.push_back(&item); 18 } 19 20 // できたかな? 21 for ( foo& item : src ) { 22 std::cout << (void*)&item << " " << item.value() << std::endl; 23 } 24 std::cout << std::endl; 25 for ( foo* item : dst ) { 26 std::cout << (void*)item << " " << item->value() << std::endl; 27 } 28}

投稿2023/03/18 06:30

編集2023/03/19 06:36
episteme

総合スコア16614

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

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

ianaka3

2023/03/19 00:22

episteme様 回答いただき、ありがとうございます。 記載の方法で試してみたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問