2

ポインターを交換しようとしていますが、アクセス エラーしか表示されません。これを行う方法はありますか?

void Swap(someObject *first, someObject *next)
{
     delete first;
     first = next;
     // I'm guessing this delete first pointer as well ?
     delete next;
     next = new someObject();
};

メソッドの明確化: 最初に 2 番目と交換し、2 番目に「someObject」の新しいインスタンスを作成する必要があります。= FIRST = SECOND、SECOND = FIRST のように交換しないでください。最初が 2 番目になり、2 番目が新しいオブジェクトまたはオブジェクトへの新しいポインターになります。

2 番目 = 次。

解決

void Swap(someObject*& first, someObject*& next)
{
    std::swap(first, next);
    next = new someObject();
};
4

4 に答える 4

3

はい、ありますが、何かが欠けています。を渡すsomeObject *firstと、関数には、渡したポインターのコピーがあり、 という名前が付けられfirstます。したがって、 の値をfirst変更すると、ローカル変数の値が変更され、元の変数には反映されません。

あなたがする必要があるのは、この方法でポインタへの参照を渡すことです:

void Swap(someObject*& first, someObject*& second)
{
     delete first;    // Will delete whatever first points to
     first = second;
     delete second;   // first will now point to a deallocated object, you'd better set first = nullptr
     second = new someObject();    // Will really set second to something new
};

2 つのポインターを交換するだけの場合は、標準ライブラリのユーティリティ関数を使用することもできますstd::swap

それが役立つことを願っています。

于 2012-08-21T20:52:23.660 に答える
2

その特定のスニペットにアクセス エラーはないはずですが、実際には両方のメモリ ロケーションを削除しています。

関数の外では、両方のポインターがぶら下がっていることに注意してください。変更しているのではなく、コピーしているためです。

関数の外部で変更を永続化するには、参照によってポインターを渡す必要があります。

void Swap(someObject*& first, someObject*& second)

このバージョンを呼び出した後second、有効な場所を指しますが、そうでfirstはありません (メモリを削除し、ポインターを再割り当てしていないため)。

また、スワップするには、 を使用できますstd::swap。車輪を再発明しないでください。

于 2012-08-21T20:50:50.573 に答える
1

代わりに、この swap イディオムを試してください。Yours はパラメーターを変更 (および両方のオブジェクトを削除) しますが、実際には呼び出しサイトでポインター値を交換しません。

template <typename T>
void Swap(T & a, T & b)
{
    T x = a;

    a = b;
    b = x;
}

ただし、これには同じように簡単に使用できますstd::swap。このテンプレート関数が行うのと同じことを効果的に行います。

于 2012-08-21T20:53:57.947 に答える
1

せいぜいポインタのローカルコピーを交換しているだけなので、これは確かにアクセスエラーになります。渡される引数は、ポインターへの参照である必要があります。

void Swap(someObject*& first, someObject*& second)
{
   someObject* temp = first;
   first = second;
   second = temp;
};

ところで、'swap' のようなよく知られた名前の意味を、delete と new を含む恣意的な交換を意味するように変更しないでください。スワップは、それが意味するものを意味します。派手な割り当て/削除/新規を行う派手な操作が必要な場合は、別の名前を付けてください。

最初と2番目を入れ替えて、2番目に「someObject」の新しいインスタンスを作成するだけです。

これは、どのようにスライスしてもスワップではありません。私はそれを「Shift」と呼びますが、MyOperation と呼びましょう:

void MyOperation(someObject*& first, someObject*& second)
{
   someObject* temp = new someObject;
   delete first;
   first = second;
   second = temp;
};

temp がスローされる可能性が最も高く、例外が発生した場合に物事を一貫した状態に残したいため、temp がどのように事前に割り当てられているかに注意してください。削除と単純なポインターの割り当てはスローできません。

于 2012-08-21T20:53:04.217 に答える