1

私はC#プログラマーで、厄介なポインターに問題があり、間違いが何であるかを知ることができません。リストのヘルプを使用できます。

つまり、基本的に私はカードのスタックのようなものを持っており、これらのカードはリストに保存されます。一番上を取得して関数に戻したいだけです。pop_back()を使用することもできますが、最後のカードはカードバックであるため、そのままにしておく必要があります(後でテクスチャなどを使用して作成します)

Card * CardStack::HandOut()
{
    if (m_Stack.size() > 1)
    {
        list<Card *>::iterator it = m_Stack.end();
        advance(it, -2);
        Card *ret = *it;
        Card tmp = *ret;
        Card *tmpp = &tmp;
        m_Stack.remove(ret);
        return tmpp;
    }
    return NULL;
}

だから私はいつも最後から2番目のカードをポップバックしたい。私はそれが完全な初心者の間違いだと確信しています:(

4

2 に答える 2

3

ローカル変数へのポインタを返しています。

Card tmp = *ret;
Card *tmpp = &tmp;
m_Stack.remove(ret);
return tmpp;

関数が終了した後、それはもう存在しません。したがって、後でポインタを使用すると、未定義の動作が呼び出されます。

あなたは気にしないでください、tmpそしてtmpp、戻っretてそれをするべきですremove、それはカードを破壊しません、それは単にそれをスタックから取り除く(へのポインタ)。

于 2012-10-22T18:56:37.867 に答える
1

イテレータでアイテムポインタを直接消去することができます。これにより、削除が .remove() を使用した O(n) ではなく O(1) であることが保証され、コンテンツが一意でない場合に余分なアイテムが削除されるのを回避できます。

    std::list<Card*>::iterator it = m_Stack.end();
    std::advance(it, -2);
    Card* res = *it;
    m_Stack.erase(it);
    return res;

生のポインターを格納することは、C++ では慣用的ではないことに注意してください。コピーが安価な場合はオブジェクトを値で保存する (つまり を使用するlist<Card>) か、スマート ポインター ( などlist<shared_ptr<Card> >) を使用して、使用されなくなったときにメモリが自動的に収集されるようにすることをお勧めします。

于 2012-10-22T19:01:17.177 に答える