2016-08-21 6 views
-3

私は、関数とメンバ変数の束を含む冒険者クラスを与えていました。 は、そのうちの一つは次のとおりです。C++で動的な2D配列へのポインタを初期化する方法

string*** items; 

ので、最初私はそれは私が行う必要があり、3D配列だと思ったが、私はそれが2次元配列へのポインタであることを仮定と言われました。私が実行しようとしました何

は、その初期の一時配列

string** temp; 

を作成し、それを埋めるだった、私は、これは、関数が終了するまで動作します

items = &temp; 

一時

に私の項目をポイントします。次に、アイテム内のインデックス値を呼び出して呼び出します。

何もありません。 tempが消えると配列も消えます。

このラインもdoenst仕事

(*items) = new string*[2]; 

私は私を助けたオンライン何かを見つけることができませんでした。

tempを使用して作成したアイテムを初期化するか、配列データを保持するにはどうしたらいいですか?コードを求める人のために

、これは彼らが私に与えたものである:

class Adventurer{ 
private: 
    string*** items; 
    string name; 
    double maxCarryWeight; 
    double currentCarryWeight; 
    int currentNumberOfItems; 
    int maxNumberOfItems; 
    double health; 
    static int numberOfAdventurers; 


public: 
    Adventurer(); //default constructor 
    Adventurer(const Adventurer& a); //copy constructor 
    ~Adventurer(); 
    bool pickUpItem(string it, double weight); 
    bool dropItem(string it); 
    bool dropItem(int index); 
    void setName(string n); 
    string getName() const; 
    void setMaxCarryWeight(double w); 
    double getMaxCarryWeight() const; 
    void setCurrentCarryWeight(double w); 
    double getCurrentCarryWeight() const;  
    void setMaxNumberOfItems(int n); 
    int getMaxNumberOfItems() const; 
    void setCurrentNumberOfItems(int n); 
    int getCurrentNumberOfItems() const; 
    int getNumberOfAdventurers() const; 
    void setHealth(double h); 
    double getHealth() const; 
    string** getItem(int index) const; 
    Adventurer& operator = (const Adventurer& a); 
}; 

そして

string*** items; 

は、それは完全には明らかではない2D配列

+2

「ダイナミックアレイ」と考えると、次の考えは['std :: vector'](http://en.cppreference.com/w/cpp/container/vector)でなければなりません。 –

+0

ベクターを使用することはできません。 –

+0

@πάνταῥεῖIveは今では4時間のグーグル・グーグルで、何も見つからなかった。 –

答えて

0

へのポインタであることを言いましたあなたの質問から達成しようとしているものの、あなたの主な問題は、あなたの2D Cスタイルを割り当てるときにローカル変数のアドレスを返すことと思われるでしょうstd::stringアレイ。以下は、割り当てられた2D配列を返してからこの戻り値のアドレスを取得し、変数std::string*** itemsに格納することで、このような問題を回避する方法の非常に基本的な例です。コメントで述べたように

// allocate memory for a 2D C-style array of std::string's 
std::string** allocate_2d_array(std::size_t rows, std::size_t cols) { 
    std::string** items_arr = new std::string*[rows]; 
    for (std::size_t i = 0; i < rows; ++i) 
     items_arr[i] = new std::string[cols]; 
    return items_arr; 
} 
// print each element of the 2D C-style array via a pointer to the array 
void print_items(std::ostream& os, std::string*** items, std::size_t rows, std::size_t cols) { 
    for (std::size_t i = 0; i < rows; ++i) { 
     for (std::size_t j = 0; j < cols; ++j) 
      os << (*items)[i][j] << ' '; 
     os << '\n'; 
    } 
} 
// destruct the 2D C-style array 
void deallocate_2d_array(std::string** items_arr, std::size_t rows, std::size_t cols) { 
    for (std::size_t i = 0; i < rows; ++i) 
     delete[] items_arr[i]; 
    delete[] items_arr; 
} 
int main(void) { 
    std::size_t rows = 3; // matrix rows 
    std::size_t cols = 3; // matrix columns 
    // allocate a 2D array of std::string's 
    std::string** items_arr = allocate_2d_array(items, 3, 3); 
    // set the pointer to a 2D std::string array to address of items_arr 
    std::string*** items = &items_arr; 
    int count = 0; 
    // fill items_arr with data via items pointer 
    for (std::size_t i = 0; i < rows; ++i) { 
     for (std::size_t j = 0; j < cols; ++j) 
      (*items)[i][j] = std::to_string(++count); 
    } 
    print_items(std::cout, items); // print matrix to terminal 
    deallocate_2d_array(items_arr, rows, cols); // deallocate items_arr 
} 

しかし、これは++現代Cと調和しておらず、一つはむしろstd::stringインスタンスの行列を格納するのにstd::vector<std::vector<std::string>>を使用します。

あなたが std::vectorを使用することはオプションではないことを述べたが、私はあなたの先生は、おそらくそのためには、常にこれらの愚かな制約の周りに一つの方法です std::vectorと同様の意味を持つ独自のベアボーン動的配列を作るについては何も言わなかったと思われます。そのことを念頭に置いて、以下は、非常に基本的な(そして未テストの)クラスのフレームワークで、 std::vector(アロケータを使わない)を模倣しています。

template<typename Ty> 
class dynamic_array { 
public: 
    typedef Ty value_type; 
    typedef Ty& reference; 
    typedef const Ty& const_reference; 
    typedef Ty* pointer; 
    typedef const Ty* const_pointer; 
    typedef std::size_t size_type; 
    typedef std::ptrdiff_t difference_type; 
    // CONSTRUCTION/ASSIGNMENT 
    dynamic_array() 
     : arr_capacity(0), arr_size(0) {} 
    dynamic_array(size_type count) 
     : arr_capacity(count), arr_size(count) { allocate(count); } 
    ~dynamic_array() { destroy(); } 
    dynamic_array& operator=(dynamic_array _other) { 
     swap(*this, _other); 
     return *this; 
    } 
    // CAPACITY 
    bool empty() const noexcept { return arr_size; } 
    size_type size() const noexcept { return arr_size; } 
    size_type capacity() const noexcept { return arr_capacity; } 
    void reserve(size_type new_cap) { if (new_cap > arr_capacity) reallocate(new_cap); } 
    // ELEMENT ACCESS 
    reference operator[](size_type n) { return arr[n]; } 
    const_reference operator[](size_type n) const { return arr[n]; } 
    // MODIFIERS 
    void clear() { 
     for (size_type i = 0; i < arr_size; ++i) 
      (&arr[i])->~value_type(); 
     arr_size = 0; 
    } 
    void push_back(const value_type& _val) { 
     if (arr_size == arr_capacity) // TODO: expand arr using reallocate 
     pointer val = new (arr + arr_size) value_type(_val); 
     ++arr_size; 
    } 
    void pop_back() { 
     (&arr[arr_size-1])->~value_type(); 
     --arr_size; 
    } 
    void swap(dynamic_array& _other) { 
     std::swap(arr, _other.arr); 
     std::swap(arr_capacity, _other.arr_capacity); 
     std::swap(arr_size, _other.arr_size); 
    } 
    static void swap(dynamic_array& lhs, dynamic_array& rhs) { lhs.swap(rhs); } 
private: 
    value_type* arr; 
    size_type arr_capacity; 
    size_type arr_size; 
    void allocate(size_type n) { arr = new value_type[n]; } 
    void reallocate(size_type new_cap) { 
     value_type* tmp = new value_type[new_cap]; 
     size_type tmp_rows = (new_cap > arr_capacity) ? arr_capacity : new_cap; 
     for (size_type i = 0; i < tmp_rows; ++i) 
      tmp[i] = std::move(arr[i]); 
     delete[] arr; 
     arr = tmp; 
     arr_capacity = new_cap; 
    } 
    void destroy { clear(); delete[] arr; } 
}; 

は、代わりに生のポインタとそれがもたらす頭痛の多くをいじりの、あなただけのメモリ管理を心配することなく、あなたのdynamic_array<dynamic_array<std::string>>クラスのインスタンスの周囲を通過することができます。


注:上記のdynamic_arrayクラスはテストされていないと、おそらくいくつかの調整が必要で、それは(あなたがアロケータとイテレータをサポートする必要があると思います)また、STL形式のコンテナを実装するの偉大な例ではない、それだけですベアボーンstd::vectorのコンセプトをコンセプトにして、「ベクトルなし」のタスク要件を回避します。

関連する問題