C++ constructor on unnamed object idiom? - c++

I have a C++ class that works like the Linux "devmem" utility for embedded systems. I'll simplify and give an outline of it here:
struct DevMem
{
DevMem(off_t start, off_t end)
{
// map addresses start to end into memory with mmap
}
~DevMem()
{
// release mapped memory with munmap
}
uint32_t read(off_t address)
{
// return the value at mapped address
}
void write(off_t address, uint32_t value)
{
// write value to mapped address
}
};
I use it like this:
void WriteConverter(uint32_t value)
{
off_t base = 0xa0000000;
DevMem dm(base, base+0x100); // set up mapping for region
dm.write(base+0x8, value); // output value to converter
dm.write(base+0x0, 1); // strobe hardware
while (dm.read(base+0x4)) // wait until done
;
}
And this works great. RAII ensures the mapped memory is released when I'm done with it. But some hardware is really simple and only needs a single read or write. It was bothering me that in order to access that hardware, I would have to invent some name for the instantiation of the class:
DevMem whatever(0xa0001000, 0xa0001000); // map the thing
whatever.write(0xa0001000, 42); // do the thing
With the named object and the repetition of the address three times, it's a little verbose. So I made a change to the constructor so that I could leave off the end parameter if I'm only mapping a single address:
DevMem(off_t start, off_t end = 0)
{
// map addresses start to end into memory with mmap
}
And then I overloaded the read and write routines so the address wasn't passed:
uint32_t read()
{
// return the value at the constructor's start address
}
void write(uint32_t value)
{
// write value to the constructor's start address
}
And I discovered that I could then do this:
DevMem(0xa0001000).write(42); // do the thing
And this works. I don't need to invent a name for the object, it's less verbose, the value is written (or read), and RAII cleans it up nicely. What I assume is happening is that C++ is constructing an unnamed object, dereferencing it, using it, and then destructing it.
Is this use of an unnamed object valid? I mean, it compiles okay, GCC and clang don't complain with common warnings cranked up, and it does actually work on the target hardware. I just can't find any examples of such a thing on the Interwebs. Is this a named idiom?

Yep, completely valid. You create the object, use it and then the destructor kicks in. Your compiler will probably generate the same assembly in your whatever example if whateverhas a reasonable scope.
I don't know any names for this construct though. As well as I wouldn't call this an idiom.

Related

c++, dealing with exceptions from constructors

I have a class which is loaded from an external file, so ideally I would want its constructor to load from a given path if the load fails, I will want to throw an error if the file is not found/not readable (Throwing errors from constructors is not a horrible idea, see ISO's FAQ).
There is a problem with this though, I want to handle errors myself in some controlled manner, and I want to do that immediately, so I need to put a try-catch statement around the constructor for this object ... and if I do that, the object is not declared outside the try statement, i.e.:
//in my_class.hpp
class my_class
{
...
public:
my_class(string path);//Throws file not found, or other error error
...
};
//anywhere my_class is needed
try
{
my_class my_object(string);
}
catch(/*Whatever error I am interesetd in*/)
{
//error handling
}
//Problem... now my_object doesn't exist anymore
I have tried a number of ways of getting around it, but I don't really like any of them:
Firstly, I could use a pointer to my_class instead of the class itself:
my_class* my_pointer;
try
{
my_class my_pointer = new my_class(string);
}
catch(/*Whatever error I am interesetd in*/)
{
//error handling
}
The problem is that the instance of this object doesn't always end up in the same object which created it, so deleting all pointers correctly would be easy to do wrong, and besides, I personally think it is ugly to have some objects be pointers to objects, and have most others be "regular objects".
Secondly, I could use a vector with only one element in much the same way:
std::vector<my_class> single_vector;
try
{
single_vector.push_back(my_class(string));
single_vector.shrink_to_fit();
}
catch(/*Whatever error I am interesetd in*/)
{
//error handling
}
I don't like the idea of having a lot of single-element vectors though.
Thirdly, I can create an empty faux constructor and use another loading function, i.e.
//in my_class.hpp
class my_class
{
...
public:
my_class() {}// Faux constructor which does nothing
void load(string path);//All the code in the constructor has been moved here
...
};
//anywhere my_class is needed
my_class my_object
try
{
my_object.load(path);
}
catch(/*Whatever error I am interesetd in*/)
{
//error handling
}
This works, but largely defeats the purpose of having a constructor, so I don't really like this either.
So my question is, which of these methods for constructing an object, which may throw errors in the constructor, is the best (or least bad)? and are there better ways of doing this?
Edit: Why don't you just use the object within the try-statement
Because the object may need to be created as the program is first started, and stopped much later. In the most extreme case (which I do actually need in this case also) that would essentially be:
int main()
{
try
{
//... things which might fail
//A few hundred lines of code
}
catch(/*whaveter*/)
{
}
}
I think this makes my code hard to read since the catch statement will be very far from where things actually went wrong.
One possibility is to wrap the construction and error handling in a function, returning the constructed object. Example :
#include <string>
class my_class {
public:
my_class(std::string path);
};
my_class make_my_object(std::string path)
{
try {
return {std::move(path)};
}
catch(...) {
// Handle however you want
}
}
int main()
{
auto my_object = make_my_object("this path doesn't exist");
}
But beware that the example is incomplete because it isn't clear what you intend to do when construction fails. The catch block has to either return something, throw or terminate.
If you could return a different instance, one with a "bad" or "default" state, you could have just initialized your instance to that state in my_class(std::string path) when it was determined the path is invalid. So in that case, the try/catch block is not needed.
If you rethrow the exception, then there is no point in catching it in the first place. In that case, the try/catch block is also not needed, unless you want to do a bit of extra work, like logging.
If you want to terminate, you can just let the exception go uncaught. Again, in that case, the try/catch block is not needed.
The real solution here is probably to not use a try/catch block at all, unless there is actually error handling you can do that shouldn't be implemented as part of my_class which isn't made apparent in the question (maybe a fallback path?).
and if I do that, the object is not declared outside the try statement
I have tried a number of ways of getting around it
That doesn't need to be a problem. There's not necessarily need to get around it. Simply use the object within the try statement.
If you really cannot have the try block around the entire lifetime, then this is a use case for std::optional:
std::optional<my_class> maybe_my_object;
try {
maybe_my_object.emplace(string);
} catch(...) {}
The problem is that the instance of this object doesn't always end up in the same object which created it, so deleting all pointers correctly would be easy to do wrong,
A pointer returned by new is correct to delete. In the error case, simply set the pointer to null and there would be no problem. That said, use a smart pointer instead for dynamic allocation, if you were to use this approach.
single_vector.push_back(my_class(string));
single_vector.shrink_to_fit();
Don't push and shrink when you know the number of objects that are going to be in the vector. Use reserve instead if you were to use this approach.
The object creation can fail because a resource is unavailable. It's not the creation which fails; it is a prerequisite which is not fulfilled.
Consequently, separate these two concerns: First obtain all resources and then, if that succeeded, create the object with these resources and use it. The object creation as such in this design cannot fail, the constructor is nothrow; it is trivial boilerplate code (copy data etc.). If, on the other hand, resource acquisition failed, object creation and object use are both skipped: Your problem with existing but unusable objects is gone.
Responding to your edit about try/catch comprising the entire program: Exceptions as error indicators are better suited for things which are done in many places at various times in a program because they guarantee error handling (by default through an abort) while separating it from the normal control flow. This is impossible to do with classic return value examination, which leaves us with a choice between unreadable or unreliable programs.
But if you have long-lived objects which are created only rarely (in your example: only at startup) you don't need exceptions. As you said, constructor exceptions guarantee that only properly initialized objects can be used. But if such an object is only created at startup this danger is low. You check for success one way or another and exit the program which cannot perform its purpose if the initial resource acquisition failed. This way the error is handled where it occurred. Even in less extreme cases (e.g. when an object is created at the beginning of a large function other than main) this may be the simpler solution.
In code, my suggestion looks like this:
struct T2;
struct myEx { myEx(const char *); };
void exit(int);
T1 *acquireResource1(); // e.g. read file
T2 *acquireResource2(); // e.g. connect to db
void log(const char *what);
class ObjT
{
public:
struct RsrcT
{
T1 *mT1;
T2 *mT2;
operator bool() { return mT1 && mT2; }
};
ObjT(const RsrcT& res) noexcept
{
// initialize from file data etc.
}
// more member functions using data from file and db
};
int main()
{
ObjT::RsrcT rsrc = { acquireResource1(), acquireResource2() };
if(!rsrc)
{
log("bummer");
exit(1);
}
///////////////////////////////////////////////////
// all resources are available. "Real" code starts here.
///////////////////////////////////////////////////
ObjT obj(rsrc);
// 1000 lines of code using obj
}

How can I calculate a hash/checksum/fingerprint of an object in c++?

How can I calculate a hash/checksum/fingerprint of an object in c++?
Requirements:
The function must be 'injective'(*). In other words, there should be no two different input objects, that return the same hash/checksum/fingerprint.
Background:
I am trying to come up with a simple pattern for checking whether or not an entity object has been changed since it was constructed. (In order to know which objects need to be updated in the database).
Note that I specifically do not want to mark the object as changed in my setters or anywhere else.
I am considering the following pattern: In short, every entity object that should be persisted, has a member function "bool is_changed()". Changed, in this context, means changed since the objects' constructor was called.
Note: My motivation for all this is to avoid the boilerplate code that comes with marking objects as clean/dirty or doing a member by member comparison. In other words, reduce risk of human error.
(Warning: psudo c++ code ahead. I have not tried compiling it).
class Foo {
private:
std::string my_string;
// Assume the "fingerprint" is of type long.
long original_fingerprint;
long current_fingerprint()
{
// *** Suggestions on which algorithm to use here? ***
}
public:
Foo(const std::string& my_string) :
my_string(my_string)
{
original_fingerprint = current_fingerprint();
}
bool is_changed() const
{
// If new calculation of fingerprint is different from the one
// calculated in the constructor, then the object has
// been changed in some way.
return current_fingerprint() != original_fingerprint;
}
void set_my_string(const std::string& new_string)
{
my_string = new_string;
}
}
void client_code()
{
auto foo = Foo("Initial string");
// should now return **false** because
// the object has not yet been changed:
foo.is_changed();
foo.set_my_string("Changed string");
// should now return **true** because
// the object has been changed:
foo.is_changed();
}
(*) In practice, not necessarily in theory (like uuids are not unique in theory).
You can use the CRC32 algorithm from Boost. Feed it with the memory locations of the data you want to checksum. You could use a hash for this, but hashes are cryptographic functions intended to guard against intentional data corruption and are slower. A CRC performs better.
For this example, I've added another data member to Foo:
int my_integer;
And this is how you would checksum both my_string and my_integer:
#include <boost/crc.hpp>
// ...
long current_fingerprint()
{
boost::crc_32_type crc32;
crc32.process_bytes(my_string.data(), my_string.length());
crc32.process_bytes(&my_integer, sizeof(my_integer));
return crc32.checksum();
}
However, now we're left with the issue of two objects having the same fingerprint if my_string and my_integer are equal. To fix this, we should include the address of the object in the CRC, since C++ guarantees that different objects will have different addresses.
One would think we can use:
process_bytes(&this, sizeof(this));
to do it, but we can't since this is an rvalue and thus we can't take its address. So we need to store the address in a variable instead:
long current_fingerprint()
{
boost::crc_32_type crc32;
void* this_ptr = this;
crc32.process_bytes(&this_ptr, sizeof(this_ptr));
crc32.process_bytes(my_string.data(), my_string.length());
crc32.process_bytes(&my_integer, sizeof(my_integer));
return crc32.checksum();
}
Such a function does not exist, at least not in the context that you are requesting.
The STL provides hash functions for basic types (std::hash), and you could use these to implement a hash function for your objects using any reasonable hashing algorithm.
However, you seem to be looking for an injective function, which causes a problem. Essentially, to have an injective function, it would be necessary to have an output of size greater or equal to that of the object you are considering, since otherwise (from the pigeon hole principle) there would be two inputs that give the same output. Given that, the most sensible option would be to just do a straight-up comparison of the object to some sort of reference object.

How does one properly deserialize a byte array back into an object in C++?

My team has been having this issue for a few weeks now, and we're a bit stumped. Kindness and knowledge would be gracefully received!
Working with an embedded system, we are attempting to serialize an object, send it through a Linux socket, receive it in another process, and deserialize it back into the original object. We have the following deserialization function:
/*! Takes a byte array and populates the object's data members */
std::shared_ptr<Foo> Foo::unmarshal(uint8_t *serialized, uint32_t size)
{
auto msg = reinterpret_cast<Foo *>(serialized);
return std::shared_ptr<ChildOfFoo>(
reinterpret_cast<ChildOfFoo *>(serialized));
}
The object is successfully deserialzed and can be read from. However, when the destructor for the returned std::shared_ptr<Foo> is called, the program segfaults. Valgrind gives the following output:
==1664== Process terminating with default action of signal 11 (SIGSEGV)
==1664== Bad permissions for mapped region at address 0xFFFF603800003C88
==1664== at 0xFFFF603800003C88: ???
==1664== by 0x42C7C3: std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() (shared_ptr_base.h:149)
==1664== by 0x42BC00: std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() (shared_ptr_base.h:666)
==1664== by 0x435999: std::__shared_ptr<ChildOfFoo, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() (shared_ptr_base.h:914)
==1664== by 0x4359B3: std::shared_ptr<ChildOfFoo>::~shared_ptr() (shared_ptr.h:93)
We're open to any suggestions at all! Thank you for your time :)
In general, this won't work:
auto msg = reinterpret_cast<Foo *>(serialized);
You can't just take an arbitrary array of bytes and pretend it's a valid C++ object (even if reinterpret_cast<> allows you to compile code that attempts to do so). For one thing, any C++ object that contains at least one virtual method will contain a vtable pointer, which points to the virtual-methods table for that object's class, and is used whenever a virtual method is called. But if you serialize that pointer on computer A, then send it across the network and deserialize and then try to use the reconstituted object on computer B, you'll invoke undefined behavior because there is no guarantee that that class's vtable will exist at the same memory location on computer B that it did on computer A. Also, any class that does any kind of dynamic memory allocation (e.g. any string class or container class) will contain pointers to other objects that it allocated, and that will lead you to the same invalid-pointer problem.
But let's say you've limited your serializations to only POD (plain old Data) objects that contain no pointers. Will it work then? The answer is: possibly, in very specific cases, but it will be very fragile. The reason for that is that the compiler is free to lay out the class's member variables in memory in different ways, and it will insert padding differently on different hardware (or even with different optimization settings, sometimes), leading to a situation where the bytes that represent a particular Foo object on computer A are different from the bytes that would represent that same object on computer B. On top of that you may have to to worry about different word-lengths on different computers (e.g. long is 32-bit on some architectures and 64-bit on others), and different endian-ness (e.g. Intel CPUs represent values in little-endian form while PowerPC CPUs typically represent them in big-endian). Any one of these differences will cause your receiving computer to misinterpret the bytes it received and thereby corrupt your data badly.
So the remaining part of the question is, what is the proper way to serialize/deserialize a C++ object? And the answer is: you have to do it the hard way, by writing a routine for each class that does the serialization member-variable by member-variable, taking the class's particular semantics into account. For example, here are some methods that you might have your serializable classes define:
// Serialize this object's state out into (buffer)
// (buffer) must point to at least FlattenedSize() bytes of writeable space
void Flatten(uint8_t *buffer) const;
// Return the number of bytes this object will require to serialize
size_t FlattenedSize() const;
// Set this object's state from the bytes in (buffer)
// Returns true on success, or false on failure
bool Unflatten(const uint8_t *buffer, size_t size);
... and here's an example of a simple x/y point class that implements the methods:
class Point
{
public:
Point() : m_x(0), m_y(0) {/* empty */}
Point(int32_t x, int32_t y) : m_x(x), m_y(y) {/* empty */}
void Flatten(uint8_t *buffer) const
{
const int32_t beX = htonl(m_x);
memcpy(buffer, &beX, sizeof(beX));
buffer += sizeof(beX);
const int32_t beY = htonl(m_y);
memcpy(buffer, &beY, sizeof(beY));
}
size_t FlattenedSize() const {return sizeof(m_x) + sizeof(m_y);}
bool Unflatten(const uint8_t *buffer, size_t size)
{
if (size < FlattenedSize()) return false;
int32_t beX;
memcpy(&beX, buffer, sizeof(beX);
m_x = ntohl(beX);
buffer += sizeof(beX);
int32_t beY;
memcpy(&beY, buffer, sizeof(beY));
m_y = ntohl(beY);
return true;
}
int32_t m_x;
int32_t m_y;
};
... then your unmarshal function could look like this (note I've made it templated so that it will work for any class that implements the above methods):
/*! Takes a byte array and populates the object's data members */
template<class T> std::shared_ptr<T> unmarshal(const uint8_t *serialized, size_t size)
{
auto sp = std::make_shared<T>();
if (sp->Unflatten(serialized, size) == true) return sp;
// Oops, Unflatten() failed! handle the error somehow here
[...]
}
If this seems like a lot of work compared to just grabbing the raw memory bytes of your class object and sending them verbatim across the wire, you're right -- it is. But this is what you have to do if you want the serialization to work reliably and not break every time you upgrade your compiler, or change your optimization flags, or want to communicate between computers with different CPU architectures. If you'd rather not do this sort of thing by hand, there are pre-packaged libraries to assist by with (partially) automating the process, such as Google's Protocol Buffers library, or even good old XML.
The segfault during destruction occurs because you are creating a shared_ptr object by reinterpret casting a pointer to a uint8_t. During the destruction of the returned shared_ptr object the uint8_t will be released as if it is a pointer to a Foo* and hence the segfault occurs.
Update your unmarshal as given below and try it.
std::shared_ptr<Foo> Foo::unmarshal(uint8_t *&serialized, uint32_t size)
{
ChildOfFoo* ptrChildOfFoo = new ChildOfFoo();
memcpy(ptrChildOfFoo, serialized, size);
return std::shared_ptr<ChildOfFoo>(ptrChildOfFoo);
}
Here the ownership of the the ChildOfFoo object created by the statement ChildOfFoo* ptrChildOfFoo = new ChildOfFoo(); is transferred to the shared_ptr object returned by the unmarshal function. So when the returned shared_ptr object's destructor is called, it will be properly de-allocated and no segfault occurs.
Hope this help!

How to make a getter function for a double pointer?

I am needing to modify an open source project to prevent reusing code (more efficient just to create a GetGameRulesPtr() function than to keep going into the engine to retrieve it. The problem is, it is stored as void **g_pGameRules. Ive never really grasped the concept of a pointer to a pointer, and I am a bit confused.
I am creating a GetGameRules() function to retrieve this pointer, but im not sure if my getter function should be void* ret type and then return *g_pGameRules, or how exactly I should go about this. I am actually brushing on my pointer usage now, but wanted to find out the proper method to learn from.
Here is the code, lines 58-89 are the SDK function that retrieve the g_pGameRules pointer from the game engine. The other functions are what I am adding the getter function to.
// extension.cpp
class SDKTools_API : public ISDKTools
{
public:
virtual const char *GetInterfaceName()
{
return SMINTERFACE_SDKTOOLS_NAME;
}
virtual unsigned int GetInterfaceVersion()
{
return SMINTERFACE_SDKTOOLS_VERSION;
}
virtual IServer *GetIServer()
{
return iserver;
}
virtual void *GetGameRules()
{
return *g_pGameRules;
}
} g_SDKTools_API;
// extension.h
namespace SourceMod
{
/**
* #brief SDKTools API.
*/
class ISDKTools : public SMInterface
{
public:
virtual const char *GetInterfaceName() = 0;
virtual unsigned int GetInterfaceVersion() = 0;
public:
/**
* #brief Returns a pointer to IServer if one was found.
*
* #return IServer pointer, or NULL if SDKTools was unable to find one.
*/
virtual IServer* GetIServer() = 0;
/**
* #brief Returns a pointer to GameRules if one was found.
*
* #return GameRules pointer, or NULL if SDKTools was unable to find one.
*/
virtual void* GetGameRules() = 0;
};
}
// vglobals.cpp
void **g_pGameRules = NULL;
void *g_EntList = NULL;
void InitializeValveGlobals()
{
g_EntList = gamehelpers->GetGlobalEntityList();
char *addr;
#ifdef PLATFORM_WINDOWS
/* g_pGameRules */
if (!g_pGameConf->GetMemSig("CreateGameRulesObject", (void **)&addr) || !addr)
{
return;
}
int offset;
if (!g_pGameConf->GetOffset("g_pGameRules", &offset) || !offset)
{
return;
}
g_pGameRules = *reinterpret_cast<void ***>(addr + offset);
#elif defined PLATFORM_LINUX || defined PLATFORM_APPLE
/* g_pGameRules */
if (!g_pGameConf->GetMemSig("g_pGameRules", (void **)&addr) || !addr)
{
return;
}
g_pGameRules = reinterpret_cast<void **>(addr);
#endif
}
You want to return a void*, and do the casting back to the appropriate SomeType** within implementation code. This is because void** has strange semantics (which I can't find on google right now). It also tells more info to the user than they really need. The whole point of using void* to begin with was to avoid giving information to the user that they don't need.
If it is an option, I'd personally recommend avoiding void* altogether, and simply providing an opaque reference type for them to call your APIs with. One way to do this would be to define a fake structure, like struct GameObjectRef {};, and pass the user back a GameObjectRef*, casted from whatever pointer your system actually uses. This allows the user to write strongly typed code, so they can't accidentally provide the wrong pointer type to your functions, as they can with void*.
How pointers (and pointers-to-pointers) work:
Imagine you are asking me where your aunt lives. Then, I hand you a piece of paper with an address to go to. That piece of paper is a pointer to a house.
Now, take that piece of paper with the address, take a photo of it with your digital camera, and place the image onto your personal wiki site.
Now, if your sister calls, asking for your aunt's address, just tell her to look it up on your wiki. If she asks for the URL, write it on a piece of paper for her. This second piece of paper is a pointer to a pointer to a house.
You can see how an address isn't the same as the real thing. Just because someone has your website address doesn't mean they know your aunt's address. And just because they have your aunt's address doesn't mean they're knocking on her door. The same is true for pointers to objects.
You can also see how you can make copies of addresses (pointers), but that doesn't make a copy of the underlying object. When you take a photo of your aunt's address, your aunt doesn't get a shiny new house.
And you can see how dereferencing a pointer will lead you back to the original object. If you to go the wiki site, you get your aunt's address. If you drive to that address, you can leave a package on her doorstep.
Note that these aren't perfect metaphors, but they are close enough to be somewhat descriptive. Real pointers-to-pointers are a lot cleaner than those examples. They describe only two things - the type of the final object (say, GameObject), and the number of levels of indirection (say, GameObject** - two levels).
I think its not a double pointer, but a pointer to pointer, and yes if you want to get void* you must return *g_pGameRules.
The think is, that the pointers is like levels. You must show which level you want to get.
A pointer to a pointer is useful if you want have the pointer change (to a larger block of memory if you run out, for example), but keep a common reference to the item, wherever it moves.
If you are not going to be reallocating or moving the block pointed to, then dereferencinig like you have in your getter is fine. I haven't looked at the library you are using, but one thing to consider is that it may have reference counting when you get an instance in order to ensure the object isn't changed after you get the pointer.
So, what I would recommend is that you look to see if the library has any "Factory" functions or "instance" creating functions and use those.
-Dan8080

Pointer object in C++

I have a very simple class that looks as follows:
class CHeader
{
public:
CHeader();
~CHeader();
void SetCommand( const unsigned char cmd );
void SetFlag( const unsigned char flag );
public:
unsigned char iHeader[32];
};
void CHeader::SetCommand( const unsigned char cmd )
{
iHeader[0] = cmd;
}
void CHeader::SetFlag( const unsigned char flag )
{
iHeader[1] = flag;
}
Then, I have a method which takes a pointer to CHeader as input and looks
as follows:
void updateHeader(CHeader *Hdr)
{
unsigned char cmd = 'A';
unsigned char flag = 'B';
Hdr->SetCommand(cmd);
Hdr->SetFlag(flag);
...
}
Basically, this method simply sets some array values to a certain value.
Afterwards, I create then a pointer to an object of class CHeader and pass it to
the updateHeader function:
CHeader* hdr = new CHeader();
updateHeader(hdr);
In doing this, the program crashes as soon as it executes the Hdr->SetCommand(cmd)
line. Anyone sees the problem, any input would be really appreciated
When you run into a crash, act like a crime investigator: investigate the crime scene.
what is the information you get from your environment (access violation? any debug messages? what does the memory at *Hdr look like? ...)
Is the passed-in Hdr pointer valid?
Then use logical deduction, e.g.:
the dereferencing of Hdr causes an access violation
=> passed in Hdr points to invalid memory
=> either memory wasn't valid to start with (wrong pointer passed in), or memory was invalidated (object was deleted before passing in the pointer, or someone painted over the memory)
...
It's probably SEGFAULTing. Check the pointers.
After
your adding some source code
your comment that the thing runs on another machine
the fact that you use the term 'flag' and 'cmd' and some very small datatypes
making me assume the target machine is quite limited in capacity, I suggest testing the result of the new CHeader for validity: if the system runs out of resources, the resulting pointer will not refer to valid memory.
There is nothing wrong with the code you've provided.
Are you sure the pointer you've created is the same same address once you enter the 'updateHeader' function? Just to be sure, after new() note the address, fill the memory, sizeof(CHeader), with something you know is unique like 0XDEAD, then trace into the updateHeader function, making sure everything is equal.
Other than that, I wonder if it is an alignment issues. I know you're using 8 bit values, but try changing your array to unsigned ints or longs and see if you get the same issue. What architecture are you running this on?
Your code looks fine. The only potential issue I can see is that you have declared a CHeader constructor and destructor in your class, but do not show the implementation of either. I guess you have just omitted to show these, else the linker should have complained (if I duplicate this project in VC++6 it comes up with an 'unresolved external' error for the constructor. It should also have shown the same error for the destructor if you had a... delete hdr; ...statement in your code).
But it is actually not necessary to have an implementation for every method declared in a class unless the methods are actually going to get called (any unimplemented methods are simply ignored by the compiler/linker if never called). Of course, in the case of an object one of the constructor(s) has to be called when the object is instantiated - which is the reason the compiler will create a default constructor for you if you omit to add any constructors to your class. But it will be a serious error for your compiler to compile/link the above code without the implementation of your declared constructor, so I will really be surprised if this is the reason for your problem.
But the symptoms you describe definitely sounds like the 'hdr' pointer you are passing to the updateHeader function is invalid. The reason being that the 1st time you are dereferencing this pointer after the updateHeader function call is in the... Hdr->SetCommand(cmd); ...call (which you say crashes).
I can only think of 2 possible scenarios for this invalid pointer:
a.) You have some problem with your heap and the allocation of memory with the 'new' operator failed on creation of the 'hdr' object. Maybe you have insufficient heap space. On some embedded environments you may also need to provide 'custom' versions of the 'new' and 'delete' operator. The easiest way to check this (and you should always do) is to check the validity of the pointer after the allocation:
CHeader* hdr = new CHeader();
if(hdr) {
updateHeader(hdr);
}
else
//handle or throw exception...
The normal behaviour when 'new' fails should actually be to throw an exception - so the following code will cater for that as well:
try{
CHeader* hdr = new CHeader();
} catch(...) {
//handle or throw specific exception i.e. AfxThrowMemoryException() for MFC
}
if(hdr) {
updateHeader(hdr);
}
else
//handle or throw exception...
}
b.) You are using some older (possibly 16 bit and/or embedded) environment, where you may need to use a FAR pointer (which includes the SEGMENT address) for objects created on the heap.
I suspect that you will need to provide more details of your environment plus compiler to get any useful feedback on this problem.