我正在为几个队列进行模拟。 我应该在开头输入队列数,然后模拟所有的队列。
每个“圆”的每个队列的输出同时是服务总数和每个队列的大小。
我的程序崩溃了,没有回应。
它写出第一个队列,然后崩溃...
帮助!
我认为我的计算错了,但我不知道,因为它全都崩溃了。
这是:
#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");
}
答案 0 :(得分:2)
我建议您使用Application Verifier等程序来查找导致崩溃的问题:
http://www.microsoft.com/en-us/download/details.aspx?id=20028
了解如何调试软件并了解正在发生的事情非常重要。请在调试器(Visual Studio,Eclipse)中运行您的代码,并查看它停止的位置。如果您使用了应用程序验证程序,那么它可能会停止发生问题的位置。看看变量,看看它们是否有意义。看看你是否正在访问不应该访问的内存位置。
要在Visual Studio中使用Application Verifier,请安装它,然后在C:\ Windows的System32文件夹中找到appVerifier.exe。然后打开文件并将其指向可执行文件。启用您认为正确的检查。然后在visual Studio中运行它。
答案 1 :(得分: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
在这里,我们看到程序在a中发生了分段故障
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
输出结尾处所述。这是因为在计算Customers
时未处理inLine
为mean
{{1}}的情况。