Re: Issues in generating unique time id using virtual memory address
ittium wrote:
Group,
I came across a timer implementation where to generate unique timer id,
implementer has used virtual memory address. In the program written below,
using new, 1 byte memory is allocated, this memory is kept reserved till timer
expiry. Since this address will be unique (in program virtual memory),
uniqueness of timer id is guaranteed. This code is used in a multi-threaded
program and is supposed to generate unique ids on 32bit and 64bit machines. The
code always work fine during unit testing. But in field trials (code running for
more than a month or so) , some time, we have seen on a 32 bit machine code
generates junk timerId.
How do you determine when the timerId is junk?
Are you trying to narrow that BYTE8 back to the pointer type and are not finding
the original BYTE8* there? How are you doing the reverse conversion?
I doubt a possible heap corruption, but we can not run
memory profilers in field trials. Please go through the code. I have added my
comments, where I think code might have some issue.
#include <iostream>
#include <stdlib.h>
using namespace std;
typedef uint64_t BYTE8;
typedef unsigned char BYTE;
#define _AAANEW(ptr,structClass) \
try \
{ \
ptr = NULL; // Comment - not needed but see the catch block
ptr = new structClass; \
} \
catch(...) \
{ \
if(ptr == NULL) \
{ \
cout<<"Failure in _AAANEW, exiting the process";\
exit(0); \
} \
}
BYTE8 getTimerId()
{
BYTE* timer;
_AAANEW(timer,BYTE); //Comment - On 32 bit machine, timer will
//contain 32 bit virtual memory address
/* Timer id is taken as BYTE 8 since timer Id will be generated
on 32 bit an 64 bit also */
BYTE8 timerId = (BYTE8)timer; //Comment - I am not sure
// whether for 32 bit machine this
//conversion is safe
It is safe as long as BYTE8 is a large enough integer to hold the value of the
pointer (which should hold in your situation), but see below:
Theoretically, reinterpret_cast which is IMHO what is applied here for the
explicit cast conversion can change representation, so you might want to
double-check check you are not using some fancy union stuff when you are
converting the BYTE8 back to BYTE*.
return timerId;
}
thanks
Ittium
HTH
-Pavel