使用堆栈和队列分段故障

时间:2015-09-26 17:33:11

标签: c++

我是使用堆栈和队列的新手,我遇到了内存问题。你能给我一些关于我做错的一点见解吗?这应该是使用堆栈和队列的战争游戏的实现。

#ifndef WAR_H
#define WAR_H
/*
  This runWar function runs a game of war between 2 automated players
  and returns the number of rounds (both put a card down 
  once per round) until someone won.  An integer is given 
  as an upper limit to how many rounds a game can go on for.
*/
#include <iostream>
#include <stdlib.h>
#include <stdexcept>
#include <stack>
#include <queue>

#include "deck.h"

using namespace std;

int decide(Card, Card, unsigned int&);

int runWar(unsigned int limit)
{
  Deck d;
    queue<Card> p1;
    queue<Card> p2;

    while(d.size() != 0)
    {
        p1.push(d.getTopCard());
        if(d.size() != 0)
        {
            p2.push(d.getTopCard());
        }   
    }

    bool winner = false; //checks if anyone won
    unsigned int roundcount = 0; //checks number of comparisons
    while(roundcount<limit && winner == false)
    {
        Card one = p1.front();
        Card two = p2.front();

        p1.pop();
        p2.pop();
        if(one.getRank() > two.getRank())
        {
            roundcount++;
            p1.push(one);   
            p1.push(two);
        }
        else if(one.getRank() < two.getRank())
        {
            roundcount++;
            p2.push(one);   
            p2.push(two);
        }
        else
        {
            stack<Card> pile;
            //3 cards off the top each
            bool war_done = false;
            while(war_done == false)
            {
                for(unsigned int w=0; w<3; w++)
                {
                    pile.push(p1.front());
                    pile.push(p2.front());
                    p1.pop();
                    p2.pop();
                }
                Card p11 = p1.front();
                Card p22 = p2.front();
                pile.push(p11);
                pile.push(p22);
                p1.pop();
                p2.pop();
                if(p11.getRank() > p22.getRank())
                {
                    roundcount++;
                    while(!(pile.empty()))
                    {
                        p1.push(pile.top());
                        pile.pop();
                    }
                    p1.push(one);   
                    p1.push(two);
                    war_done = true;
                }
                else if(p11.getRank() > p22.getRank())
                {
                    roundcount++;
                    while(!(pile.empty()))
                    {
                        p2.push(pile.top());
                        pile.pop();
                    }
                    p2.push(one);   
                    p2.push(two);
                    war_done = true;
                }
            }
            if(p1.empty() || p2.empty())
            {
                winner = true;
            }
        }
    }
  return roundcount;
}



#endif





 int main()
{
    for(unsigned int i=0; i<19; i++)
    {
        cout<<runWar(1000)<<endl;
    }           
  return 0;
}

我的卡片和甲板课程找到了。 getTopCard()基本上是一个返回顶部卡片的pop。 getRank()表示它是2-Ace。此外,int main()位于driver.cpp文件中。

Valgrind输出:

    ==3942== Memcheck, a memory error detector
==3942== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==3942== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==3942== Command: ./doWar
==3942== 
==3942== Conditional jump or move depends on uninitialised value(s)
==3942==    at 0x4023BA: runWar(unsigned int) (war.h:77)
==3942==    by 0x4016F6: main (doWar.cpp:18)
==3942== 
==3942== Conditional jump or move depends on uninitialised value(s)
==3942==    at 0x40201B: runWar(unsigned int) (war.h:45)
==3942==    by 0x4016F6: main (doWar.cpp:18)
==3942== 
==3942== Use of uninitialised value of size 8
==3942==    at 0x401FCD: runWar(unsigned int) (war.h:41)
==3942==    by 0x4016F6: main (doWar.cpp:18)
==3942== 
==3942== Invalid read of size 4
==3942==    at 0x401FCD: runWar(unsigned int) (war.h:41)
==3942==    by 0x4016F6: main (doWar.cpp:18)
==3942==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==3942== 
==3942== 
==3942== Process terminating with default action of signal 11 (SIGSEGV)
==3942==  Access not within mapped region at address 0x0
==3942==    at 0x401FCD: runWar(unsigned int) (war.h:41)
==3942==    by 0x4016F6: main (doWar.cpp:18)
==3942==  If you believe this happened as a result of a stack
==3942==  overflow in your program's main thread (unlikely but
==3942==  possible), you can try to increase the size of the
==3942==  main thread stack using the --main-stacksize= flag.
==3942==  The main thread stack size used in this run was 8388608.
==3942== 
==3942== HEAP SUMMARY:
==3942==     in use at exit: 1,728 bytes in 6 blocks
==3942==   total heap usage: 33 allocs, 27 frees, 8,952 bytes allocated
==3942== 
==3942== LEAK SUMMARY:
==3942==    definitely lost: 0 bytes in 0 blocks
==3942==    indirectly lost: 0 bytes in 0 blocks
==3942==      possibly lost: 0 bytes in 0 blocks
==3942==    still reachable: 1,728 bytes in 6 blocks
==3942==         suppressed: 0 bytes in 0 blocks
==3942== Rerun with --leak-check=full to see details of leaked memory
==3942== 
==3942== For counts of detected and suppressed errors, rerun with: -v
==3942== Use --track-origins=yes to see where uninitialised values come from
==3942== ERROR SUMMARY: 31 errors from 4 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)

1 个答案:

答案 0 :(得分:0)

在每个&#39; pop()&#39;之前检查它是空的还是不像

 If(!p1.empty()){
   p1.pop();
 }