【问题标题】:Simulation program [closed]模拟程序[关闭]
【发布时间】:2012-12-10 17:45:04
【问题描述】:

我正在为多个队列进行模拟。 我应该在开始时输入队列数,然后模拟所有这些。

每个“轮”的每个队列的输出是同时,服务的总数和每个队列的大小。

我的程序崩溃并且没有响应。

它写出第一个队列 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");




}

【问题讨论】:

  • 运行模拟,很快我注意到inLine = cashiers[i]-&gt;size()inLine 设置为0。这导致mean = (totTime/inLine) 导致除以零错误。
  • 为了将来参考,如果您避免使用特定于 Windows 的 #includes(例如 conio.hdos.hwindows.h),您可能会在 Stack Overflow 上获得更好的运气。我们中的许多人不使用 Windows,删除这些包含只是贡献者和答案之间的另一项任务。

标签: c++ queue simulation


【解决方案1】:

我建议您使用应用程序验证程序等程序来查找导致崩溃的问题:

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

了解如何调试软件并了解发生了什么非常重要。请在调试器(Visual Studio、Eclipse)中运行您的代码并查看它停止的位置。如果您使用了应用程序验证程序,那么它可能会在问题所在的位置停止。看看变量,看看它们是否有意义。看看你是否在访问你不应该访问的内存位置。

要将 Application Verifier 与 Visual Studio 一起使用,请安装它,然后在 C:\Windows 的 System32 文件夹中找到 appVerifier.exe。然后打开文件并将其指向您的可执行文件。启用您认为正确的检查。然后在 Visual Studio 中运行。

【讨论】:

  • 谢谢!我会试试的。虽然我知道在我的最后一个 for 循环中发生了魔法崩溃。我尝试了几种解决方案,但没有任何效果:/
【解决方案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 的输出末尾所述。这是因为计算mean时没有处理Customers不是inLine的情况。

【讨论】:

  • 好的,谢谢!我修复了它,但它现在永远不会进入 if 。我将 inLine =cashiers->size() 放在 if now 之前。我必须以某种方式填写它。这就像我不添加到队列中..
猜你喜欢
  • 1970-01-01
  • 2013-09-02
  • 1970-01-01
  • 1970-01-01
  • 2017-01-12
  • 2016-03-12
  • 1970-01-01
  • 2015-02-25
  • 2013-03-25
相关资源
最近更新 更多