5

非常に単純な C++ プログラムでオブジェクトにメモリを動的に割り当てようとしています (現在ほど動的ではありませんが、最終的にはそうなるでしょう) 。私はクラスに不慣れで、最近 C++ を使い始めたばかりで、C を置き去りにしています。コードは次のとおりです。

#include <iostream>
using namespace std;

class Test {
  private:
    int i;
  public:
    Test(int);
    ~Test();
    void print();
};

Test::Test(int ii) { i = ii; }
Test::~Test() { i=0; cout << "deconstructor called...value of i= " << i << endl; }
void Test::print() { cout << "value of i= " << i << endl; }

int main()
{
  Test a(10),*b,*c;
  //a.print(); // this works

  b = new Test(12);
  //b->print(); // this works as well

  for (int i=0; i<2; i++)
    c = new Test(i);

  c->print(); /* this shows that the value of i=1 .. should be 0? */
  c[0].print(); /* as expected (I guess), this prints i=1 as well... [expected because c->print() shows i=1 also */
  c[1].print(); /* shows value of i=0... */

  //delete []c; /* this fails miserably, but `delete c` works, why :( */

}

私の混乱の多くは、実際にはコード自体のコメントに含まれています。私は基本的に、配列の各要素がそれ自体のオブジェクトである配列cを作成しようとしています。

私が取得しているコードの動作は、コメントに記載されています。

4

6 に答える 6

5

与えられたコードにはいくつかの深刻な問題があります。

  1. 実行newしている*bが、それを逃したdelete
  2. ループで*c数回上書きしているため、メモリリークが発生します。forポインタから新しいリソースを割り当てる前に、常にリソースの割り当てを解除してください。
  3. で割り当てる場合は、それぞれnew/new[]/mallocでポインタの割り当てを解除する必要がありますdelete/delete[]/free。あなたが維持していないのと同じです*c(それが失敗する理由です)。

また、動的割り当ての学習とは別に、動的リソースを処理するためのより良い方法を提供するSTLコンテナーにも注意する必要があります。例:std::vector

于 2011-07-25T03:30:56.363 に答える
5

おそらく、私たちはあなたが持っている拡張された宣言を見る必要があります:

Test a(10);
Test *b;
Test *c;

bとcをテストへのポインターとして定義しましたが、cをテストへのポインターの配列にしたいようです。あなたが意図したcの宣言はおそらく次のとおりです。

Test **c;

これを初期化します:

c = new Test*[2];

for (int i=0; i<2; i++)
   c[i] = new Test(i);

このようにアクセスします:

c[0]->print();
c[1]->print();
于 2011-07-25T03:34:03.800 に答える
0

delete[]が機能しないことは完全に正常です。cを配列としてではなく、ポインタとして割り当てました。配列のアドレスをポインタに格納することもできますが、それだけです。forループは、新しく割り当てられたオブジェクトへのポインタを同じポインタに繰り返し格納するだけなので、なぜ正確にc [1]が機能するのか、実際には疑問に思っています(配列にデータを入力していません!)。

于 2011-07-25T03:34:31.537 に答える
0
for (int i=0; i<2; i++)
    c = new Test(i);

上記のコードはメモリをリークします。cループ反復で最後に構築されたオブジェクトを指すだけです。

c->print(); /* これは、i=1 .. の値が 0 であるべきであることを示していますか?

ここでは、 でc構築された場所を指しnew Test(1);ます。というわけで、アウトプット。

すべてのnew[]にはdelete[]を、newにはdeleteを付ける必要があります。両方を混在させることはできません。

于 2011-07-25T03:27:40.173 に答える