Login or Sign up Help | Site Map
Connecting Tech Pros Worldwide

Assertion Failure

Question posted by: IanWright (Member) on July 24th, 2008 08:30 AM
I'm struggling with an assertion failure and was wondering if anyone can help. I understand why its failing, but don't quite have the C++ knowledge to be able to decide how it should be fixed...

The line that causes the fault is within the updateStats_thread() method.

Code: ( text )
  1. delete(tq_current);


This works while there are still more elements within the timing queue. However once we reach the last one, so tq_current->next looks like garbage it errors with a _BLOCK_TYPE_IS_VALID failing its check on phead->nBlockUse.

I've tried things like if(tq_current->next) which if I'm not mistaken checks that tq_current->next is not null before deleting it, but that didn't work and never entered the code at all...

I've listed the structures of the queue, the PERIODS are set to different times in seconds. Also I've shown the update code where the actual timing queue appears to get added to... Any advice would be muchly appreciated!

Code: ( text )
  1. typedef struct _timingQueue {
  2.   struct timeval time ;
  3.   double qryTime ;
  4.   struct _timingQueue *next ;
  5. } TimingQueue ;


Code: ( text )
  1. // updates the timing queues
  2. double timing(char *msg, struct timeval t1, struct timeval t2)
  3. {
  4.   double rtn = timediff(t1, t2);
  5.  
  6.     TimingQueue *tqp = new TimingQueue ;
  7.     tqp->time = t1 ;
  8.     tqp->qryTime = rtn ;
  9.     tqp->next = NULL ;
  10.  
  11.     pthread_mutex_lock(&timingMutex) ;
  12.     timeQEnd->next = tqp ;
  13.     timeQEnd = tqp ;
  14.     pthread_mutex_unlock(&timingMutex) ;
  15.  
  16.   if (msg)
  17.     sprintf (msg, "%f", rtn) ;
  18.   return(rtn) ;
  19. }



Code: ( text )
  1. void * updateStats_thread(void *)
  2. {
  3.     double lastQueryAvg1 = -1 ;
  4.     double lastQueryAvg2 = -1 ;
  5.     double lastQueryAvg3 = -1 ;
  6.     double lastQueryAvg1Cnt = 0 ;
  7.     double lastQueryAvg2Cnt = 0 ;
  8.     double lastQueryAvg3Cnt = 0 ;
  9.     int period1 = 0 ;
  10.     int period2 = 0 ;
  11.     int period3 = 0 ;
  12.     double currentDiff ;
  13.  
  14.     double totalQueryTime1=0.0;
  15.     double totalQueryTime2=0.0;
  16.     double totalQueryTime3=0.0;
  17.  
  18.     struct timeval now ;
  19.     struct timeval then ;
  20.  
  21.     gettimeofday(&then, NULL) ;
  22.  
  23.     while (running) {
  24.  
  25.         // First of all, let's only bother with updates if the window is visible.
  26.         if (visible) {
  27.             period1 = 0 ;
  28.             period2 = 0 ;
  29.             period3 = 0 ;
  30.             totalQueryTime1=0.0;
  31.             totalQueryTime2=0.0;
  32.             totalQueryTime3=0.0;
  33.  
  34.             gettimeofday(&now, NULL) ;
  35.  
  36.             // And only update every 5 seconds.
  37.             if (now.tv_sec - then.tv_sec >= UPDATE_PERIOD)
  38.             {
  39.                 TimingQueue *tq_current = timeQ.next ;
  40.                 TimingQueue *tq_prev = &timeQ ;
  41.  
  42.                 while (tq_current)
  43.                 {
  44.                     double currentDiff = timediff(tq_current->time, now) ;
  45.                     if (currentDiff >= 0) {
  46.                         if (currentDiff <= PERIOD1)
  47.                         {
  48.                             totalQueryTime1+=tq_current->qryTime;
  49.                             period1++ ;
  50.                         }
  51.                         if (currentDiff <= PERIOD2)
  52.                         {
  53.                             totalQueryTime2+=tq_current->qryTime;
  54.                             period2++ ;
  55.                         }
  56.                         if (currentDiff <= PERIOD3) {
  57.                           totalQueryTime3+=tq_current->qryTime;
  58.                           period3++ ;
  59.                         } else {
  60.                             // drop it from the queue
  61.                             if (tq_current != timeQEnd)
  62.                             {
  63.                                 tq_prev->next = tq_current->next ;
  64.                             } else {
  65.                                 pthread_mutex_lock(&timingMutex) ;
  66.                                 timeQEnd->next = NULL ;
  67.                                 timeQEnd = tq_prev ;
  68.                                 pthread_mutex_unlock(&timingMutex) ;
  69.                             }
  70.  
  71.                             delete(tq_current);
  72.                             tq_current = NULL ;
  73.                             break ;
  74.                         }
  75.                     }
  76.                     tq_current = tq_current->next ;
  77.                 }
  78.                 /* Don't change the stats if we haven't been doing anything */
  79.                 if (period1 > lastQueryAvg1Cnt)
  80.                 {
  81.                     lastQueryAvg1 = totalQueryTime1/period1;
  82.                 }
  83.                 lastQueryAvg1Cnt = period1;
  84.  
  85.                 if (period2 > lastQueryAvg2Cnt)
  86.                 {
  87.                     lastQueryAvg2 = totalQueryTime2/period2;
  88.                 }
  89.                 lastQueryAvg2Cnt = period2;
  90.                 if (period3 > lastQueryAvg3Cnt)
  91.                 {
  92.                     lastQueryAvg3 = totalQueryTime3/period3;
  93.                 }
  94.                 lastQueryAvg3Cnt = period3;
  95.  
  96.                 char msg[100];
  97.                 WCHAR wMsg[100] ;
  98.                 sprintf (msg, "Avg qry load: %3.2f, %3.2f, %3.2f qry/s",
  99.                     period1/PERIOD1, period2/PERIOD2, period3/PERIOD3) ;
  100.                 wsprintf (wMsg, L"%hs",msg) ;
  101.                 SetWindowText(StatusLines[queryThrougput], wMsg) ;
  102.                 sprintf (msg, "Avg qry time: %3.2f, %3.2f, %3.2f s", lastQueryAvg1, lastQueryAvg2, lastQueryAvg3) ;
  103.                 wsprintf (wMsg, L"%hs",msg) ;
  104.                 SetWindowText(StatusLines[queryAvgTime], wMsg) ;
  105.                 then = now ;
  106.             }
  107.         }
  108.         Sleep(1000) ;
  109.     }
  110.     return NULL ;
  111. }
Would you like to answer this question?
Sign up for a free account, or Login (if you're already a member).
Banfa's Avatar
Banfa
AdministratorVoR
4,912 Posts
July 24th, 2008
12:09 PM
#2

Re: Assertion Failure
Quote:
Originally Posted by IanWright
Code: ( text )
  1. <snip>
  2.                                 timeQEnd->next = NULL ;
  3.                                 timeQEnd = tq_prev ;
  4. <snip>
These 2 lines of code are the wrong way round.

Reply
IanWright's Avatar
IanWright
Member
75 Posts
July 24th, 2008
01:51 PM
#3

Re: Assertion Failure
Quote:
Originally Posted by Banfa
These 2 lines of code are the wrong way round.


Banfa, thanks very much, it appears you are correct. Could you explain why this is the case, as I'm not sure even after looking at it...

Thanks,

Ian

Reply
Banfa's Avatar
Banfa
AdministratorVoR
4,912 Posts
July 24th, 2008
05:05 PM
#4

Re: Assertion Failure
OK taking a look at an abstract list of n items then the last 2 items would be

Item(n-1){Data, Next=&Item(n)}
Item(n){Data, Next=NULL}

I hope you understand my syntax, and the end, previous and current pointers are

EndPtr = &Item(n)
PrevPtr = &Item(n-1)
CurrentPtr = &Item(n)

When you execute

1: EndPtr->Next = NULL;
2: EndPtr = PrevPtr;
3: FreeMemory(CurrentPtr);


Then EndPtr is pointing to item(n) so line 1 NULLs the already NULL Next Pointer in item(n), line 2 Sets EndPtr to point at item(n-1) and line 3 releases the memory of item(n). You are left with

Item(n-1){Data, Next=&Item(n)}
EndPtr = &Item(n-1)

Note that the Next pointer of the last item in them list now (item(n-1)) still points to where item(n) used to be but that that memory location has been freed, ie it is no longer valid.

If on the same list you execute

1: EndPtr = PrevPtr;
2: EndPtr->Next = NULL;
3: FreeMemory(CurrentPtr);

The line 1 sets EndPtr to item(n-1), line 2 sets the next pointer of EndPtr, which is now item(n-1) to NULL and line 3 releases the memory of item(n). You are left with

Item(n-1){Data, Next=NULL}
EndPtr = &Item(n-1)

Note that now the next pointer in item(n-1) is NULL.

In most lists the Next pointer of the final entry is supposed to be NULL as a marker they way you had it did not preserve this end condition. However by swaping the 2 lines of code I suggested you altered the structure that EndPtr->Next = NULL; operated on so that it did preserve the list end condition correctly.

Reply
IanWright's Avatar
IanWright
Member
75 Posts
July 25th, 2008
07:53 AM
#5

Re: Assertion Failure
Banfa,

Thanks very much. I do understand your syntax and I think I also understand your explanation, but its much appreciated!

Ian

Reply
Reply
Not the answer you were looking for? Post your question . . .
182,196 Experts ready to help you find a solution.
Sign up for a free account, or Login (if you're already a member).

Top C / C++ Forum Contributors