0

複数のキューのシミュレーションを作成しています。最初にキューの数を入力してから、それらすべてをシミュレートすることになっています。

各「ラウンド」の各キューの出力は、その間、サービスの合計数、および各キューのサイズです。

プログラムがクラッシュして応答しません。

最初のキュー och を書き出してからクラッシュします...

ヘルプ!

私の計算は間違っていると思いますが、すべてクラッシュしているのでわかりません。

ここにあります:

#include <iostream>
#include <cstdlib>
#include <list>
#include <ctime>
#include<conio.h>
#include <time.h>
#include <stdlib.h>
#include<dos.h>
#include<windows.h>


using namespace std;

class Customer
{
public:

int servicet;
int served;

Customer()
{
    servicet= rand()%150+30;
}

int getServicetime()
{
    return servicet;
}

int getServed()
{
    return served;
}


int decreaseServeTime()
{
    servicet --;
}

};


int totServed=0;
int queues=0;
int inLine=0;
int totTime=0;
int smallestQueue=0;
int temp=0;
int ran=0;
double mean=0;
int served=0;
int serviceTime=0;
int help=0;
int sim=0;
int n=0;
using namespace std;
int main()
{
cout<<"Number of Cashiers?: "<<endl;
cin >> queues;
cout <<"How long simulation?: "<<endl;
cin >> sim;

list<Customer> *cashiers[queues];
list<Customer> *cust;


for(int i=0; i<=queues; i++)
{
    cust = new list<Customer>;
    cashiers[i] = cust;


}

srand(time(0));
while(n<sim)
{
    Sleep(2000);


    ran= rand()%4;
    smallestQueue = cashiers[0] ->size();

    for(int j=0; j<ran; j++)
    {
        for(int k=0; k<queues; k++)
        {
            temp = cashiers[k]->size();

            if(temp<=smallestQueue)
            {
                smallestQueue = temp;

                help=k;
            }
        }

        Customer C;

        cashiers[help]->push_back(C);
        inLine++;

    }

    for(int i=0; i<queues; i++)
    {
        if(serviceTime>0)
        {

            serviceTime = cashiers[i]->front().getServicetime();
            cashiers[i]->front().decreaseServeTime();

        }
        else if(serviceTime==0)
        {
            cashiers[i]->pop_front();
            served++;
        }
    }

    totTime++;
    int cash=1;
    for(int i=0; i<queues; i++)
    {
        if(inLine!=0)
        {
            cout <<"Kassa: "<<cash<<endl;
            inLine = cashiers[i]->size();
            mean = (totTime/inLine);
            totServed +=served;
            cash++;


        }
         cout <<inLine<<" "<<mean<<" "<<totServed<<endl;
    }


n++;
}

system("pause");




}
4

2 に答える 2

2

Application Verifier などのプログラムを使用して、クラッシュの原因となっている問題を見つけることをお勧めします。

http://www.microsoft.com/en-us/download/details.aspx?id=20028

ソフトウェアをデバッグする方法を学び、何が起こっているのかを理解することが重要です。デバッガー (Visual Studio、Eclipse) でコードを実行し、停止する場所を確認してください。Application Verifier を使用した場合は、問題が発生した場所で停止する可能性があります。変数を見て、意味があるかどうかを確認してください。すべきではないメモリの場所にアクセスしているかどうかを確認します。

Visual Studio で Application Verifier を使用するには、それをインストールしてから、C:\Windows の System32 フォルダーで appVerifier.exe を見つけます。次に、ファイルを開き、実行可能ファイルをポイントします。適切なチェックと思われるものを有効にします。次に、Visual Studio で実行します。

于 2012-12-10T17:53:02.597 に答える
2

開始するのに適した場所は、デバッガーです (例: gdb)。まず、デバッグを有効にしてコンパイルし ( g++ -ggdb)、デバッガーで実行してみます。

 $ g++ hi.cpp  -ggdb
 $ gdb ./a.out 
 GNU gdb (GDB) 7.5-ubuntu
 Copyright (C) 2012 Free Software Foundation, Inc.
 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
 This is free software: you are free to change and redistribute it.
 There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
 and "show warranty" for details.
 This GDB was configured as "x86_64-linux-gnu".
 For bug reporting instructions, please see:
 <http://www.gnu.org/software/gdb/bugs/>...
 Reading symbols from /home/ben/a.out...done.
 (gdb) run
 Starting program: /home/ben/a.out 
 Number of Cashiers?: 
 5
 How long simulation?: 
 5
 Kassa: 1

 Program received signal SIGSEGV, Segmentation fault.
 0x0000000000401827 in std::_List_const_iterator<Customer>::operator++ (
     this=0x7fffffffdd10) at /usr/include/c++/4.7/bits/stl_list.h:236
 236        _M_node = _M_node->_M_next;
 (gdb) backtrace
 #0  0x0000000000401827 in std::_List_const_iterator<Customer>::operator++ (
     this=0x7fffffffdd10) at /usr/include/c++/4.7/bits/stl_list.h:236
 #1  0x0000000000401665 in std::__distance<std::_List_const_iterator<Customer> >
     (__first=..., __last=...)
     at /usr/include/c++/4.7/bits/stl_iterator_base_funcs.h:82
 #2  0x0000000000401492 in std::distance<std::_List_const_iterator<Customer> > (
     __first=..., __last=...)
     at /usr/include/c++/4.7/bits/stl_iterator_base_funcs.h:118
 #3  0x000000000040135b in std::list<Customer, std::allocator<Customer> >::size
     (this=0x604010) at /usr/include/c++/4.7/bits/stl_list.h:855
 #4  0x0000000000401122 in main () at hi.cpp:125

ここでは、関数のセグメンテーション違反でプログラムがクラッシュしたことがわかりますstd::list。しばらくプログラミングを行った後、これはおそらく、プログラムが本来あるべきではないメモリを踏みにじっているためであるという直感が得られます。valgrind問題の性質を大まかに特定したので、この種の問題を具体的に追跡するためのツールである に切り替えます。

 $ valgrind ./a.out
 ==13751== Memcheck, a memory error detector
 ==13751== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
 ==13751== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
 ==13751== Command: ./a.out
 ==13751== 
 Number of Cashiers?: 
 5
 How long simulation?: 
 5
 Kassa: 1
 ==13751== Invalid read of size 8
 ==13751==    at 0x401422: std::list<Customer, std::allocator<Customer> >::begin() const (stl_list.h:749)
 ==13751==    by 0x40134F: std::list<Customer, std::allocator<Customer> >::size() const (stl_list.h:855)
 ==13751==    by 0x401121: main (hi.cpp:125)
 ==13751==  Address 0x5a06040 is 0 bytes inside a block of size 16 free'd
 ==13751==    at 0x4C2A44B: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
 ==13751==    by 0x4018E7: __gnu_cxx::new_allocator<std::_List_node<Customer> >::deallocate(std::_List_node<Customer>*, unsigned long) (new_allocator.h:100)
 ==13751==    by 0x4017D9: std::_List_base<Customer, std::allocator<Customer> >::_M_put_node(std::_List_node<Customer>*) (stl_list.h:339)
 ==13751==    by 0x4015C0: std::list<Customer, std::allocator<Customer> >::_M_erase(std::_List_iterator<Customer>) (stl_list.h:1549)
 ==13751==    by 0x4013E9: std::list<Customer, std::allocator<Customer> >::pop_front() (stl_list.h:983)
 ==13751==    by 0x40108B: main (hi.cpp:113)
 ==13751== 
 ==13751== 
 ==13751== Process terminating with default action of signal 8 (SIGFPE)
 ==13751==  Integer divide by zero at address 0x402CCCE98
 ==13751==    at 0x40113C: main (hi.cpp:126)

ここではvalgrind、プログラムが未割り当てのメモリで読み取り操作を試みたことを示しています。特に、これは手術の結果として起こっているようpop_frontです。cashiers[i]ソースを見ると、最初にサイズを確認せずにポップしようとしています。

適切なチェックを追加できます。

 ...
 else if(serviceTime==0)
 {
     if (!cashiers[i]->empty()) {
         cashiers[i]->pop_front();
         served++;
     }
 }
 ...

ただし、クラッシュの実際の原因は、 の出力のmean最後に示されているように、 を計算する際のゼロ除算です。valgrindこれは、 を計算する際に、アールがない場合CustomersinLine扱わないためmeanです。

于 2012-12-10T18:01:48.943 に答える