From: jack DOT stinchcombe AT usa DOT net Newsgroups: comp.os.msdos.djgpp Subject: problem with referenced structure Date: Sat, 22 May 1999 00:48:27 GMT Organization: Deja.com - Share what you know. Learn what you don't. Lines: 467 Message-ID: <7i4usr$mg7$1@nnrp1.deja.com> NNTP-Posting-Host: 206.17.119.174 X-Article-Creation-Date: Sat May 22 00:48:27 1999 GMT X-Http-User-Agent: Mozilla/4.08 [en] (Win95; I ;Nav) X-Http-Proxy: 1.0 x43.deja.com:80 (Squid/1.1.22) for client 206.17.119.174 To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com I am using a structure to store most of the data the program needs. main then passes the structure on as a reference varible to the functions it calls. Im using a structure like this to avoid having functions with lots of paramaters. My problem is that in some cases when I assign a structure member in these functions, it assigns the value to a different member than the one specified in the code. First I found that although the clerk_events[] member of the QueueData was dimensioned correctly, with the code int clerk_events[NUMBER_OF_CLERKS]; but when the program assigned the subscript NUMBER_OF_CLERKS for this array, the value for the structure member customer_count was changed instead . I worked around this problem by increasing the dimension of the array, as you can see at line 36: int clerk_events[NUMBER_OF_CLERKS+1]; However I have now come across a problem I cant seem to work around. On line 295, which reads data.prev_customer_count=data.customer_count; I find that the value for data.clock_time is changed! I can't figure how this kind of thing could logically happen. So what I need to know is: how could this happen, and what I can do about it? The only thing I can think of is re-organising the program so it doesnt store and access its data in this way, but if you've an easier solution, i'd really appreciate it. I have got version 2.8.1 of DJGPP and Windows 95. I compile the program using gxx, and the program needs to be compiled with the -fguiding-decls flag because Dqueue.h needs it, and of course with the -g flag for the debugger. I have pasted the code for my program below. Basically what the program is trying to do is simlulate a queue in a shop, and report back on various things. I know I have used some non-c++ code (e.g pointers and 'printf'), but thats just because im more familiar with them than the c++ equivalents. I cant post Dqueue.h here because it is copyright. Dqueue.h is an implementation of a queue ADT. (Line 1 of the program is the first commented line of asterisks. ) //**************************************************************** //** ** //** IMPORTANT: GNU C++, compile with -fguiding-decls flag. ** //** ** //**************************************************************** #include #include #include #include #include "Dqueue.h" #include #define SIMULATION_LENGTH 1 #define MAX_CUSTOMER_ARRIVAL_INTERVAL 60 #define CUSTOMER_SERVICE_TIME_MIN 10 #define CUSTOMER_SERVICE_TIME_MAX 180 #define SERVICE_RECORD_UPDATE_INTERVAL 10 #define ASSUMED_MAX_CUSTOMERS 200 #define NUMBER_OF_QUEUES 1 #define NUMBER_OF_CLERKS 2 #define CUSTOMER_EVT 1 #define CLERK_EVT 2 #define RECORD_EVT 3 #define true 1 #define false 0 struct QueueData{ Queue Q[NUMBER_OF_QUEUES]; int clerk_idletime[NUMBER_OF_CLERKS];//the total amount of time each clerk has been idle int customer_record[ASSUMED_MAX_CUSTOMERS];//the total amount of time each customer was in the shop //this is needed to calculate the average amount of time //each customer was in the shop int clerk_events[NUMBER_OF_CLERKS+1];//the time at which each clerk will become free //its a mystery why the array subscript needs to be //NUMBER_OF_CLERKS +1, but if it isnt, customer_count //gets corrupted. int customer_count;//the total number of customers during the simulation int customer_event;// time that the next customer will arrive in the shop int clock_time;//the current simluation time int clerk_index;//index of the clerk in a CLERK_EVT int event_time;//the time of the next event int prev_customer_count; int service_record[10*SIMULATION_LENGTH*3600/SERVICE_RECORD_UPDATE_INTERVAL, 1]; int update_event;//the ime of the next record update event }; int clerk_event (QueueData &data); int customer_event (QueueData &data); int customerservicetime (void); int find_next_event (QueueData &data); char *formathms (int seconds, char *charbuf); char *formatms (int seconds, char *charbuf); int getRand (int a, int b); int initialise (QueueData &data); int is_simulation_running (QueueData &postshop); void output_results (QueueData &data); int queues_empty(Queue *q); int record_event (QueueData &data); int which_queue (Queue *q); int main (void){ assert(SIMULATION_LENGTH>0); assert((NUMBER_OF_QUEUES==NUMBER_OF_CLERKS)||(NUMBER_OF_QUEUES==1)); QueueData postshop; initialise(postshop); // //loop the simluation until all queues are empty and the simulation //duration has passed while (is_simulation_running(postshop)) { // switch (find_next_event(postshop)) { case CLERK_EVT: clerk_event (postshop); break; case CUSTOMER_EVT: customer_event (postshop); break; case RECORD_EVT: record_event (postshop); break; } }//end of while loop output_results(postshop); getc(stdin); return 0; } int queues_empty(Queue *q) { int q_empty=0; //determine if all the queues are empty for (int queue_index=0;queue_indexempty()); } return (q_empty==NUMBER_OF_QUEUES); } int which_queue (Queue *q) { //find shortest queue if any //shortest_q_index the index of the shortest queue //shortest_q_length is the length of the shortest queue int shortest_q_index=-1; int shortest_q_length; //start by assuming the 1st queue is the shortest shortest_q_length=(q+0)->length(); //use a loop to find the shortest queue. for (int queue_index=0;queue_index(q+queue_index)->length()) { shortest_q_length=(q+queue_index)->length(); shortest_q_index=queue_index; } } //return index of the shortest queue or index of random queue //if queue lengths are equal or return 1 if theres only one queue if (NUMBER_OF_QUEUES==1) return 0; return (shortest_q_index==-1)?getRand(0,NUMBER_OF_QUEUES-1):shortest_q_index; } int customerservicetime (void) { return getRand (CUSTOMER_SERVICE_TIME_MIN, CUSTOMER_SERVICE_TIME_MAX); } int getRand (int a, int b) { assert (a1)?data.clerk_index-1:0].deQueue(); data.customer_record[misc]= data.clock_time-data.customer_record[misc,0]; //update when the clerk will be free next data.clerk_events[data.clerk_index]=customerservicetime()+data.clock_tim e; } else //if there's no-one in any of the queues then ... { //the clerk is going to be idle untill a customer arrives, //so the record of how much idle time that clerk has had //must increase data.clerk_idletime[data.clerk_index]+= data.customer_event-data.clock_time; //re-schedule the event to occur when a customer arrives //trouble line data.clerk_events[data.clerk_index]=data.customer_event; data.clerk_index=0; } return 0; } int is_simulation_running (QueueData &data) { return (data.clock_time<=(SIMULATION_LENGTH*3600) || !queues_empty(&data.Q[0]));} int customer_event (QueueData &data) { //a customer arrives in the shop and is added to one of the queues //the trick is here to not add a customer if he's //going to arrive beyond end of the simllation. However //the clock still needa to be updated, and a time for //another to arrive chosen, so that the program doesnt //get stuck on the same event data.clock_time=data.customer_event; if (data.clock_time<=(SIMULATION_LENGTH*3600)) { data.customer_count++; int wq=which_queue(&data.Q[0]); data.Q[wq].enQueue(data.customer_count); //make a record of when the customer arrived data.customer_record[data.customer_count]=data.clock_time; } //Get the arrival time for the next customer //This needs to be done even if its beyond the simulation time because //else the program will think that the customer_event is still the next //event and will get stuck on the same event data.customer_event=getRand(0, MAX_CUSTOMER_ARRIVAL_INTERVAL)+data.clock_time; return 0; } int record_event (QueueData &data) { data.clock_time=data.update_event; //make a record of how many customers were deal with data.service_record [(data.update_event/SERVICE_RECORD_UPDATE_INTERVAL)-1,0]= data.customer_count-data.prev_customer_count; //set time time for the next reord update event data.update_event+=SERVICE_RECORD_UPDATE_INTERVAL; //calculate the average time each customer spent in the office int average_time=0; for (int loop_index=data.prev_customer_count;loop_index<=data.customer_count; loop_index++) average_time+=data.customer_record[loop_index]; if (data.customer_count-data.prev_customer_count>0) {average_time=(int)(average_time/(data.customer_count-data.prev_customer _count));} else {average_time=-1;} data.service_record [(data.update_event/SERVICE_RECORD_UPDATE_INTERVAL)-1,1] =average_time; //update prev_customer_count data.prev_customer_count=data.customer_count; return 0; } char *formatms (int seconds, char *charbuf) { //formats seconds into mintues:seconds format //Returns the same pointer to charbuf as in the second //paramater int minutes=(int)(seconds/60); sprintf(charbuf,"%2d:%02d", minutes, seconds-(minutes*60)); return charbuf; } char *formathms (int seconds, char *charbuf) { //formats seconds into hours:mintues:seconds format //Returns the same pointer to charbuf as in the second //paramater int minutes=(int)(seconds/60); seconds-=minutes*60; int hours=(int)(minutes/60); minutes-=hours*60; sprintf(charbuf,"%d hours, %d minutes, %d seconds.", hours, minutes, seconds); return charbuf; } void output_results (QueueData &data) { FILE *output; //output=fopen ("A21B.out","w"); output=stdout; //output general info char timebuffer[40]; printf ("Length of Simulation: %s\n", formathms (data.clock_time, timebuffer)); printf ("Number of Customers: %d\n", data.customer_count); printf ("Number of Queues: %d\n", NUMBER_OF_QUEUES); printf ("Number of Clerks: %d\n\n", NUMBER_OF_CLERKS); //output service record fprintf (output,"Service Time Customers Average Time in Office\n"); int loop_index; int start_srvc_time=0; for (loop_index=0; loop_index<(int)(data.clock_time/SERVICE_RECORD_UPDATE_INTERVAL); loop_index++) { fprintf (output,"%3d - %3d %2d %s", start_srvc_time, start_srvc_time+SERVICE_RECORD_UPDATE_INTERVAL-1, data.service_record[loop_index, 0], formatms (data.service_record[loop_index, 1], timebuffer)); start_srvc_time+=SERVICE_RECORD_UPDATE_INTERVAL; } //output the clerks idle times. fprintf (output, "Clerk Idle Time\n"); for (loop_index=1;loop_index<=NUMBER_OF_CLERKS;loop_index++){ fprintf (output, " %d %s\n", loop_index, formatms (data.clerk_idletime[loop_index], timebuffer)); } return; } --== Sent via Deja.com http://www.deja.com/ ==-- ---Share what you know. Learn what you don't.---