Exception handling C++ and Qt

A

Ady

Hi,

I'm not sure if this is the place to ask this so please bear with me just in
case you are able to help.

I am writing an application using Nokias Qt Creator on Windows and C++
(because it's free) which is intended to examine the contents of a data file
byte-by-byte and generating an output of byte, short int and long int values
depending on the position of what the user has selected. All this works.
However, when I try to add a QDateTime variable to the program and I move
the relevant data segment to the variable, then try to use the .isValid()
function I always get an access violation which Qt can't handle.

I know I'm doing something daft here, and I'm quite new to C++. If anyone
can point me in the right direction it would be appreciated.

I am posting the relevant section of code.

void Widget::examinedata()
{ //let the user select a starting byte and the dump the contents //of
a byte, word and longword. The text is already displayed char *ptr;
unsigned char byteval; short wordval; unsigned short uwordval; long
longval; unsigned long ulongval; QDateTime dt; QString sDate;
ptr = hexdump->pointerval() + buffer; //buffer pointer is calculated when
the user memcpy(&byteval,ptr,1); //releases the mouse
button wordval = 0; uwordval = 0; longval = 0; ulongval = 0; //get
word and longword values so long as we're not past the end of the buffer
if ((long)hexdump->pointerval() <= (long)(fsize - sizeof(wordval)))
{ memcpy(&wordval,ptr,sizeof(wordval));
memcpy(&uwordval,ptr,sizeof(uwordval)); } if
((long)hexdump->pointerval() <= (long)(fsize - sizeof(longval)))
{ memcpy(&longval,ptr,sizeof(longval));
memcpy(&ulongval,ptr,sizeof(ulongval)); } if
((long)hexdump->pointerval() <= (long)(fsize - sizeof(dt))) {
memcpy(&dt,ptr,sizeof(dt)); } sDate = "invalid"; try { if
(dt.isValid()) sDate = dt.toString("dd/MM/yyyy hh:mm"); }
catch(...) { sDate = "Error!!"; } //output the results
lbldata->setText(QString("<html>Char: %1<br><br>") .arg(byteval) +
QString("sWord: %1<br>") .arg(wordval) + QString("uWord:
%1<br><br>") .arg(uwordval) + QString("sLong: %1<br>")
..arg(longval) + QString("uLong: %1") .arg(ulongval) +
QString("sDate: %1") .arg(sDate) +
QString("</html>") );}
 
A

Ady

Let's try this again...

void Widget::examinedata()
{
//let the user select a starting byte and the dump the contents
//of a byte, word and longword. The text is already displayed
char *ptr;
unsigned char byteval;
short wordval;
unsigned short uwordval;
long longval;
unsigned long ulongval;
QDateTime dt;
QString sDate;

ptr = hexdump->pointerval() + buffer; //buffer pointer is calculated
when the user
memcpy(&byteval,ptr,1); //releases the mouse button

wordval = 0; uwordval = 0;
longval = 0; ulongval = 0;

//get word and longword values so long as we're not past the end of the
buffer
if ((long)hexdump->pointerval() <= (long)(fsize - sizeof(wordval)))
{
memcpy(&wordval,ptr,sizeof(wordval));
memcpy(&uwordval,ptr,sizeof(uwordval));
}
if ((long)hexdump->pointerval() <= (long)(fsize - sizeof(longval)))
{
memcpy(&longval,ptr,sizeof(longval));
memcpy(&ulongval,ptr,sizeof(ulongval));
}
if ((long)hexdump->pointerval() <= (long)(fsize - sizeof(dt)))
{
memcpy(&dt,ptr,sizeof(dt));
}
sDate = "invalid";
try
{
qDebug() << "before isValid";
if (dt.isValid())
sDate = dt.toString("dd/MM/yyyy hh:mm");
qDebug() << "after isValid";
}
catch(...)
{
sDate = "Error!!";
}
//output the results
lbldata->setText(QString("<html>Char: %1<br><br>") .arg(byteval) +
QString("sWord: %1<br>") .arg(wordval) +
QString("uWord: %1<br><br>") .arg(uwordval) +
QString("sLong: %1<br>") .arg(longval) +
QString("uLong: %1") .arg(ulongval) +
QString("sDate: %1") .arg(sDate) +
QString("</html>")
);
}
 
J

Jens Thoms Toerring

Ady said:
I'm not sure if this is the place to ask this so please bear with me just in
case you are able to help.
I am writing an application using Nokias Qt Creator on Windows and C++
(because it's free) which is intended to examine the contents of a data file
byte-by-byte and generating an output of byte, short int and long int values
depending on the position of what the user has selected. All this works.
However, when I try to add a QDateTime variable to the program and I move
the relevant data segment to the variable, then try to use the .isValid()
function I always get an access violation which Qt can't handle.
I know I'm doing something daft here, and I'm quite new to C++. If anyone
can point me in the right direction it would be appreciated.
I am posting the relevant section of code.

It's, even when reformated, nearly impossible to understand what the
code is meant to do - too many important variables are not defined
etc. But I noticed that you do something here that looks rather
fishy:

QDateTime dt;
....
memcpy(&dt,ptr,sizeof(dt));

While already reading binary POD data from a file is proble-
matic (unless they got written by the same type of machine)
writing out a whole class instance and then trying to read
it back in again is a nice recipe for disaster. It might
work for very simple classes (non-polymorphic, no virtual
functions, only POD member data etc. and then only if you
use the same architecture and compiler and, maybe even the
same compiler version), for more complicated classes it
won't. Serialize the data of the class before writing them
to the file. Or at least convert the date to some integer
type (e.g. the number of seconds since some fixed point in
time) and write that out. That's still horrible and will
bite you if you should ever try to read in the file on a
different architecture than where the file was written on,
but it's at least a tiny bit saner;-)

Regards, Jens
 
R

Richard

[Please do not mail me a copy of your followup]

"Ady" <[email protected]> spake the secret code
QDateTime dt;
if ((long)hexdump->pointerval() <= (long)(fsize - sizeof(dt)))
{
memcpy(&dt,ptr,sizeof(dt));
}

memcpy on classes is undefined behavior. memcpy is only defined for
POD types.

You'll have to extract the data some other way.
 
M

Michael Doubez

I am writing an application using Nokias Qt Creator on Windows and C++
(because it's free) which is intended to examine the contents of a data file
byte-by-byte and generating an output of byte, short int and long int values
depending on the position of what the user has selected. All this works.
However, when I try to add a QDateTime variable to the program and I move
the relevant data segment to the variable, then try to use the .isValid()
function I always get an access violation which Qt can't handle.

I know I'm doing something daft here, and I'm quite new to C++. If anyone
can point me in the right direction it would be appreciated.

No it is not. serialization is actually quite common.
I am posting the relevant section of code.
[snip: code]

The read code is not sufficient, you should also post how you wrote
the file.

Quickly reading the Qt documentation, I notice there is a QDataStream
class used for (de)serializing data. May be you can use it for writing/
reading your file.
 
A

Ady

I am writing an application using Nokias Qt Creator on Windows and C++
(because it's free) which is intended to examine the contents of a data
file
byte-by-byte and generating an output of byte, short int and long int
values
depending on the position of what the user has selected. All this works.
However, when I try to add a QDateTime variable to the program and I move
the relevant data segment to the variable, then try to use the .isValid()
function I always get an access violation which Qt can't handle.

I know I'm doing something daft here, and I'm quite new to C++. If anyone
can point me in the right direction it would be appreciated.

No it is not. serialization is actually quite common.
I am posting the relevant section of code.
[snip: code]

The read code is not sufficient, you should also post how you wrote
the file.

Quickly reading the Qt documentation, I notice there is a QDataStream
class used for (de)serializing data. May be you can use it for writing/
reading your file.

--
Michael


Michael,

I feel some further explanation is required here. My program was originally
intended to emulate the DUMP command from the OpenVMS operating system (my
day job) on a Windows box. That bit of the program works so I decided to
extend it allow the user to examine the contents of the file - ANY file. It
may be a formatted file, it might not, it's whatever the user decides to
look into. It's a tool I've found useful over the years.

I'm using this as a tutorial for myself in both C++ and the Qt environment.
I am used to 'legacy' languages on VMS like C, Cobol, Basic, Fortran, Pascal
and Assembler but I'm relatively new to Windows languages.

In answer to your post, there is therefore no writing of the original file.
The file is selected by the user, opened, read into an appropriately sized
buffer (malloc'd) and closed. The data is displayed in a hex dump window and
a Ascii window (if a printable character). The user can then click or
double-click on any byte displayed in the hex dump and the values of the
various simple data types are displayed. I was hoping to add a date type but
this is where I'm getting the access violations.

If there is a simple way of translating a 64-bit date 'type' under Qt I
would really like to see it. It doesn't seem to have anything like the
SYSTEMTIME and FILETIME structures that are available under VC++ 6.

Regards,

Ady
 
J

Joshua Maurice

memcpy on classes is undefined behavior.  memcpy is only defined for
POD types.

You'll have to extract the data some other way.

A type defined with the "class" keyword can be POD. "class" and
"struct" differ solely in the default visibility of members and the
default "visibility type" of inheritance.

I agree that writing to a non-POD type with memcpy is undefined
behavior. Don't do it.
 
M

Michael Doubez

Michael Doubez said:
I am writing an application using Nokias Qt Creator on Windows and C++
(because it's free) which is intended to examine the contents of a data
file
byte-by-byte and generating an output of byte, short int and long int
values
depending on the position of what the user has selected. All this works.
However, when I try to add a QDateTime variable to the program and I move
the relevant data segment to the variable, then try to use the .isValid()
function I always get an access violation which Qt can't handle.
I know I'm doing something daft here, and I'm quite new to C++. If anyone
can point me in the right direction it would be appreciated.

No it is not. serialization is actually quite common.
I am posting the relevant section of code.

[snip: code]

The read code is not  sufficient, you should also post how you wrote
the file.

Quickly reading the Qt documentation, I notice there is a QDataStream
class used for (de)serializing data. May be you can use it for writing/
reading your file.

I feel some further explanation is required here. My program was originally
intended to emulate the DUMP command from the OpenVMS operating system (my
day job) on a Windows box. That bit of the program works so I decided to
extend it allow the user to examine the contents of the file - ANY file. It
may be a formatted file, it might not, it's whatever the user decides to
look into. It's a tool I've found useful over the years.
[snip]

In answer to your post, there is therefore no writing of the original file.
The file is selected by the user, opened, read into an appropriately sized
buffer (malloc'd) and closed. The data is displayed in a hex dump window and
a Ascii window (if a printable character). The user can then click or
double-click on any byte displayed in the hex dump and the values of the
various simple data types are displayed. I was hoping to add a date type but
this is where I'm getting the access violations.

IIRC you have a binary dump of your memory.
If there is a simple way of translating a 64-bit date 'type' under Qt I
would really like to see it. It doesn't seem to have anything like the
SYSTEMTIME and FILETIME structures that are available under VC++ 6.

SYSTEMTIME and FILETIME are C structure (POD in C++). As Richard
pointed out, QDateTime is not POD. Looking into QT headers, it seems
QtDate Time is composed of a QDate and a QTime but QDate, at least,
has virtual functions. This means the layout of the class may include
additional (RTTI) data and/or member layout reorganisation.

In short, the internal joined data is 64 bits (depending on compiler's
paddings) but there should also be a vtable pointer somewhere causing
the access violation you get; this is also plateform specific.

A solution could be to interpret your 64 bits into two unsigned int
and use them to initialise a QDateTime structure.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,954
Messages
2,570,116
Members
46,704
Latest member
BernadineF

Latest Threads

Top