2016-04-28 5 views
0

ポインタの値を自分のクラスベクトルに配置しようとしていますが、メモリエラーを受け取りました。誰でも助けてくれますか?ポインタによるメモリエラー

class myVector 
{ 
    int * vector; 
    int size; 
public: 
    myVector() 
    { 
     size = 0; 
     vector = nullptr; 
    } 


    void pushBack(int data) 
    { 
     if (size == 0) 
     { 
      *vector = data; 
      size++; 
     } 
     else 
     { 
      int * tmp = new int[size + 1]; 
      for (int i = 0; i <= size; i++) 
       tmp[i] = vector[i]; 
      tmp[size + 1] = data; 
      vector = tmp; 
      delete[] tmp; 
     } 
    } 
+1

「ベクトル」に割り当てたものを '[削除]する必要はありません。それは単なるぶら下がりのポインタです。 'delete []'はデストラクタになければなりません。 –

+3

'push = pushBack'のif文のように、' size == 0'のとき、 '* vector = data;'はどうなりますか?それはあなたに答えを与えるはずです。 –

+2

@bkVnet:はい、それはとにかく最初のハードルです。たくさんのものがあります。 –

答えて

1

プッシュバックを使用する場合は、あなたのポインタにデータを割り当てようが、ポインタがあなたのコンストラクタでnullptrに設定されています。

nullptrにデータを割り当てることはお勧めできません。

vector = new int[1]; 
*vector = data; 

あなたのケースで動作するはずです。 もう1つの良いアイデアは、ベクトルをコンストラクタで初期化することです。さらに

delete[] tmp; 

は危険である、削除は別の方法であなたのデストラクタに添加することができます。

+3

'vector = &data;'はローカル変数のアドレスを格納します。 –

+0

* vector = data; nullptrにデータを割り当てます。 – Nils

+2

@Nilsはいですが、 'vector =&data'はローカル変数のアドレスを格納します。そのローカル変数は、それが宣言された関数( 'pushback')が返った後で終了し、ポインタメンバは、もはや存在しない変数の無効なメモリアドレスで終わるでしょう。 –

2

私の意見では、コードには多くの問題があります。しかし、私はあなたが尋ねた問題だけに取り組んでいきます。他の人が指摘しているように、ポインタvectorを作成し、それをnullptrに初期化しました。そして、あなたはnullptrにデータを保存しようとしています。これはあなたが直面しているメモリの問題を解決するはずです。

MyVector { 
... 

MyVector() : size(0), vector(new int[1]){ } 

... 
} 
+0

ええ、私は同じことを考えましたが、データでベクターをどのようにして正確に初期化するかを理解できませんでした。 – inside133

1

このようなクラスを効率的に設計するには、STLベクタのように容量を定義するなど、多くのことを考慮する必要があります。しかし、迅速な実装は次のようになります。コードhereを試してみてください。

#include <iostream> 
using namespace std; 

class myVector 
{ 
    int* vector_; 
    int size_; 
public: 
    myVector() : size_(0), vector_(nullptr) 
    {} 

    ~myVector() { 
     delete[] vector_; 
    } 

    int size() const { 
     return size_; 
    } 

    int operator[](int i) const { 
     return vector_[i]; 
    } 

    void pushBack(int data) 
    { 
     int* tmp = new int[size_ + 1]; 
     for (int i = 0; i < size_; i++) 
      tmp[i] = vector_[i]; 
     tmp[size_] = data; 
     delete vector_; 
     vector_ = tmp; 
     ++size_; 
    } 
}; 

int main() { 
    myVector vec; 
    vec.pushBack(10); 
    vec.pushBack(2); 
    vec.pushBack(7); 

    for(int i = 0; i < vec.size(); ++i) 
     cout << vec[i] << endl; 

    return 0; 
} 

メンバーvector_はデストラクタで削除されることに注意してください。プッシュバックでメモリをtmpに割り当ててそこから削除すると、ぶら下がっているポインタが残ってしまいます。

+1

あなたは 'new []'を使ったのでデストラクタで 'delete [] vector_;'にする必要がありますか? –

+0

@bkVnet Right!ありがとう。更新しました。 –

0

これは役に立ちますが、パラメータ化されたコンストラクタのelse部分にエラーがあるかどうかわかりません。あなたがサイズで、新しい一時「size_ + 1」を作成するときループ自体は「ベクトル」の境界の外に出ると、その後に割り当てるので、この温度のインデックスは、「size_」にの範囲temp [size_ + 1]は、何らかの種類のメモリエラーを引き起こす可能性があります。 "user2229960"によって投稿された回答は、から "サイズ_-1"にループを実行し、temp [size_]に新しい値を割り当ててこのエラーを修正します。

関連する問題