visual c++ 2013 memory leak wostringstream, imbue & locale facets - c++

Related to my previous question, I assumed that memory leak occurs in std::string, but taking a deeper look, I got some strange results. Let's begin:
Consider we have a global
static volatile std::wostringstream *Log = nullptr;
and in a WriteToLog() function we have following code:
std::wostringstream* new_log = new std::wostringstream(std::ios::in | std::ios::out);
new_log->imbue(CConsumer::GetUtf8Locale());
std::wostringstream* old_log = (std::wostringstream*)Log;
while((std::wostringstream *)::InterlockedCompareExchangePointer((PVOID volatile *)&Log, new_log, (PVOID)old_log) != new_log)
{
::SleepEx(10, FALSE);
}
std::string logtext(Hooker::Utf16ToUtf8(old_log->str()));
which utilizes proprietary:
static std::locale FORCEINLINE GetUtf8Locale()
{
static std::unique_ptr<std::codecvt_utf8_utf16<wchar_t>> code_cvt(new std::codecvt_utf8_utf16<wchar_t>(std::codecvt_mode::generate_header | std::codecvt_mode::little_endian));
return std::locale(std::locale(), code_cvt.get());
}
Since log events occurs occasionally, it generates enormous memory leak (from initial 5MB/500 handles it jumps to 200MB/300,000 handles in a matter of minutes).
Previously, I assumed it's a leak in relation to std::string, but, using Visual Studio Profiler, it shows that all leaks are caused by GetUtf8Locale().
Can anybody help me with this issue?

This answer is wrong and I overlooked the "Compare" part of InterlockedCompareExchangePointer. However, I think it's a step in the right direction.
So we start with an object who's Log member points at 0x87654321. Then two threads call WriteToLog
Thread1 Thread2
...new_log=new ...
(now new_log=0x15331564)
...new_log=new ...
(now new_log=0x25874963)
...old_log=Log;
(now old_log=0x87654321)
...old_log=Log;
(now old_log=0x87654321)
InterlockedCompareExchangePointer
(now new_log=0x87654321)
(now Log=0x15331564)
InterlockedCompareExchangePointer
(now new_log=0x15331564)
(now Log=0x25874963)
...stuff... ...stuff...
delete old_log
(now 0x87654321 is deleted)
delete old_log
(now 0x87654321 is deleted TWICE!)
And the Log member points at 0x25874963, so... log 0x15331564 is leaked!
Your use of InterlockedCompareExchangePointer is incorrect. I think this is right, depending on the code you haven't shown.
std::wostringstream* new_log = new std::wostringstream(std::ios::in | std::ios::out);
new_log->imbue(CConsumer::GetUtf8Locale());
std::wostringstream* old_log = ::InterlockedExchangePointer((PVOID volatile *)&Log.get(), new_log);
std::string logtext(Hooker::Utf16ToUtf8(old_log->str()));
delete old_log;

Related

About _variant_t type in a MFC Library

inside my MFC (VC2010 SP1) project, I'm widely using a third party library to write some data in a database. This library is quite old (I've found it compiled for VS2005) and uses _variant_t to handle data.
In a particular case anyway I get a strange behaviour, I'll try to explain it:
// .h
struct myData
{
blastuff
CString strMyCode;
};
class MyClass
{
protected:
myData m_Foo;
};
// .cpp
// In OnInitDialog:
//...
TrdPartRecordset *pRS;
//...
pRS->GetFieldValue( _T("MyDBColumn"), m_Foo.strMyCode );
Now, I do my job and when user press OK, it's time to save to database and here start the problems:
// In OnOK
TrdPartRecordset *pRS;
//...
pRS->SetFieldValue( _T("MyDBColumn"), m_Foo.strMyCode );
Problem: if I do not modify m_Foo.strMyCode, I don't have any problem. What if I modify it? Well, if m_Foo.strMyCode does NOT contain ANY number, still have no problem.
Instead, when I have a number, I get a nasty error:
Unhandled exception at 0x77772d37 in Mosaico.exe: 0xC0000005: Access violation reading location 0x9d7077b7.
which is an attempt to read a deleted location. I've checked m_Foo in the watch and it's correct and valid, so I've digged into library source code:
BOOL TrdPartyRecordset::SetFieldValue(LPCTSTR lpFieldName, CString strValue)
{
_variant_t vtFld;
if(!strValue.IsEmpty())
vtFld.vt = VT_BSTR;
else
vtFld.vt = VT_NULL;
vtFld.bstrVal = strValue.AllocSysString();
BOOL bret = PutFieldValue(lpFieldName, vtFld);
SysFreeString(vtFld.bstrVal);
return bret;
}
What it happens is that vtFld is valid until SysFreeString and it get destroyed after it (I can see it proceding step-by-step with debugger), but ONLY WHEN I HAVE NUMBERS INTO strValue. This doesn't happen when strValue is pure alphabetical.
I've searched around the Internet and found that this kind of error happens when you double release a resource and so I've commented out SysFreeString and boom goes the dynamite: no more crashes.
Anyway is a better programmer than me so I guess that if he put that SysFreeString he had his reasons, moreover, this is the only part of my program where this mechanism crashes.
My question is: do I lose memory commenting out that SysFreeString?
Another one: do you have better solutions?
The reason is simple:
The memory is freed twice!
_variant_t has a destructor. Set the type to VT_BSTR. You also see the pojnter and type to VT_BSTR
After the function you call, you free the memory again and the destructor does the same.
The code should look like this:
_variant_t vtFld;
if(!strValue.IsEmpty())
vtFld = strValue;
else
vtFld.vt = VT_NULL;
return PutFieldValue(lpFieldName, vtFld);

Problems reading std::string from std::stringstream in C++/CLI code

I have a piece of code to read the build date and month like so. Here __DATE__ is as defined in Predefined Macros
const char* BUILD_DATE = __DATE__;
std::stringstream ss(BUILD_DATE);
std::string month;
size_t year;
ss >> month;
ss >> year;
ss >> year;
char buffer[1024];
sprintf(buffer, "Read year=[%d] month=[%s] date=[%s]", year,month.c_str(),BUILD_DATE);
When it works correcty the buffer is usually
Read year=[2013] month=[Mar] date=[Mar 9 2013]
But on some runs it is
Read year=[0] month=[M] date=[Mar 9 2013]
or
Read year=[2013] month=[Mar ] date=[Mar 9 2013]
Basically the year is either 0 or the month has an extra space.
The project is an x64/CLR build using Microsoft Visual Studio 2010 SP1 on Windows 7 box.
I am stumped as to why this happens occasionally. Am I using stringstream incorrectly ?
I was initially tempted to just delete the question but I thought I would share my findings in case some other poor soul encounters the same issue. The problem was very mysterious, never occurred on multiples runs of my application and only occurred while testing and never while debugging a test.
This innocent looking function
const char* BUILD_DATE = __DATE__;
std::stringstream ss(BUILD_DATE);
std::string month;
size_t year;
ss >> month;
ss >> year;
ss >> year;
was implemented in a C++/CLI dll. Before I can dwell into the details let me explain how the stringstream reads month and year here. To figure out how many characters constitute the month variable ss >> month needs to break the ss string buffer by space. The way it does it by using the current locale and in particular a facet of it called ctype. The ctype facet has function called ctype::is which can tell whether a character is space or not. In a well behaved C++ application everything just works according to standard. Now lets assume for some reason the ctype facet gets corrupted.
Viola, operator >> cannot determine what is a space and what isn't and cannot parse correctly. This was precisely what was happening in my case and below are the details.
The rest of the answer only applies to the std c++ library as provided by Visual Studio 2010 and how it operates under C++/CLI.
Consider some code like so
struct Foo
{
Foo()
{
x = 42;
}
~Foo()
{
x = 45;
}
int x;
};
Foo myglobal;
void SimpleFunction()
{
int myx = myglobal.x;
}
int main()
{
SimpleFunction();
return 0;
}
Here myglobal is what you call a object with static storage duration guaranteed to be initialized before main is entered and in SimpleFunction you will always see myx
as 42. The lifetime of myglobal is what we typically call per-process as in it is valid for the lifetime of the problem. The Foo::~Foo destructor will only run after main has returned.
Enter C++/CLI and AppDomain
AppDomain as per msdn provides you with isolated environment where applications execute. For C++/CLI it introduces the notion of objects of what I would call appdomain storage duration
__declspec(appdomain) Foo myglobal;
So if you changed the definition of myglobal like above you can potentially have myglobal.x be a different value in different appdomains kind of like thread local storage. So regular C++ objects of static duration are initialized/cleaned during init/exit of your program. I am using init/exit/cleaned very loosely here, but you get the idea. Object of appdomain storage are initialized/cleaned during load/unload of the AppDomain.
A typical managed program only uses the default AppDomain so per-process / per-appdomain storage is pretty much the same.
In C++ the static initialization order fiasco is a very common mistake where objects of static storage duration during their initialization refer to other objects of static storage duration that may have not been initialized.
Now consider what happens when a per-process variable refers to per-domain variable. Basically after the AppDomain is unloaded the per-process variable will refer to junk memory. For those of you who are wondering what it has to do with the original problem, please bear with me just a tad more.
Visual studio use_facet implementation
std::use_facet is used to get a facet of interest from the locale. It is used by operator << to get the ctype facet. It is defined as
template <class Facet> const Facet& use_facet ( const locale& loc );
Notice it returns a reference to Facet. The way it is implemented by VC is
const _Facet& __CRTDECL use_facet(const locale& _Loc)
{ // get facet reference from locale
_BEGIN_LOCK(_LOCK_LOCALE) // the thread lock, make get atomic
const locale::facet *_Psave =
_Facetptr<_Facet>::_Psave; // static pointer to lazy facet
size_t _Id = _Facet::id;
const locale::facet *_Pf = _Loc._Getfacet(_Id);
if (_Pf != 0)
; // got facet from locale
else if (_Psave != 0)
_Pf = _Psave; // lazy facet already allocated
else if (_Facet::_Getcat(&_Psave, &_Loc) == (size_t)(-1))
#if _HAS_EXCEPTIONS
_THROW_NCEE(bad_cast, _EMPTY_ARGUMENT); // lazy disallowed
#else /* _HAS_EXCEPTIONS */
abort(); // lazy disallowed
#endif /* _HAS_EXCEPTIONS */
else
{ // queue up lazy facet for destruction
_Pf = _Psave;
_Facetptr<_Facet>::_Psave = _Psave;
locale::facet *_Pfmod = (_Facet *)_Psave;
_Pfmod->_Incref();
_Pfmod->_Register();
}
return ((const _Facet&)(*_Pf)); // should be dynamic_cast
_END_LOCK()
}
What is happening here is we ask the locale for the facet of interest and store it in
template<class _Facet>
struct _Facetptr
{ // store pointer to lazy facet for use_facet
__PURE_APPDOMAIN_GLOBAL static const locale::facet *_Psave;
};
the local cache _Psave so that subsequent calls to get the same facet are faster. The caller of use_facet is not responsible for the returned facet life management so how are these facets cleaned up. The secret is the last part of code with comment queue up lazy facet for destruction. The _Pfmod->_Register() eventually calls this
__PURE_APPDOMAIN_GLOBAL static _Fac_node *_Fac_head = 0;
static void __CLRCALL_OR_CDECL _Fac_tidy()
{ // destroy lazy facets
_BEGIN_LOCK(_LOCK_LOCALE) // prevent double delete
for (; std::_Fac_head != 0; )
{ // destroy a lazy facet node
std::_Fac_node *nodeptr = std::_Fac_head;
std::_Fac_head = nodeptr->_Next;
_DELETE_CRT(nodeptr);
}
_END_LOCK()
}
struct _Fac_tidy_reg_t { ~_Fac_tidy_reg_t() { ::_Fac_tidy(); } };
_AGLOBAL const _Fac_tidy_reg_t _Fac_tidy_reg;
void __CLRCALL_OR_CDECL locale::facet::_Facet_Register(locale::facet *_This)
{ // queue up lazy facet for destruction
_Fac_head = _NEW_CRT _Fac_node(_Fac_head, _This);
}
Pretty smart right. Adds all the new'd facets to a linked list and clean them all using a static object destructor. Except there is a slight problem. _Fac_tidy_reg is marked as _AGLOBAL meaning all created facets are destroyed on a per-appdomain level.
The locale::facet *_Psave on the other hand is declared __PURE_APPDOMAIN_GLOBAL which seems to eventually expand to meaning per-process. So after the appdomain is cleaned up the per-process _Psave could potentially point to deleted faceted memory. This was precisely my problem. The way VS2010 Unit testing occurs is a process called QTAgent runs all your tests. Theses tests seem to be done in different appdomains on different runs by the same QTAgent process. Most likely to isolate side effects of previous test runs to effect subsequent tests. This is all well and good for fully managed code where pretty much all static storage is either thread/appdomain level but for C++/CLI which use per-process/per-appdomain incorrectly it could be a problem. The reason why I could never debug the test and ever find the problem is because the UT infrastructure always seem to spawn a new QTAgent process for debugging which means a new appdomain and a new process that has none of these problems.
I suggest trying this to see the actual date string:
cout << "Raw date: " << ss.str() << "\n";
Or stepping with a debugger and looking at the ss variable after it is created.

Cocos2d-x: Crash when initiating TMXTiledMap from string

I'm having problems creating a tmx map from string input.
bool LevelManager::initLevel(int currentLevel)
{
const char* map;
try {
map = LevelManager::getLevel(currentLevel);
} catch (int) {
throw 1;
}
if(map != NULL){
CCLog("%s", map);
tileMap = CCTMXTiledMap::create(map);
tileMap->setAnchorPoint(ccp(0,0));
tileMap->setPosition(ccp(15,20));
this->addChild(tileMap, 5);
backgoundLayer = tileMap->layerNamed("Background");
} else {
throw 1;
}
return true;
}
Thats my code.
It is very unstable. Most of the times it crashes and sometimes it doesn't.
I'm loading my map from the string map. Wich is a const *char.
My map is named Level1.tmx and when i load the map like this: tileMap = CCTMXTiledMap::create("Level1.tmx"); it always works and never crashes.
And i know for a fact that the value of map is Level1.tmx because i log it in the line before the load.
When it crashes the log outputs this: (lldb)
and on the line tileMap->setAnchorPoint(ccp(0,0)); it says "Thread 1: EXC_BAD_ACCESS (code=2, adress=0x0)
Does anyone know why this happens and how to fix it?
Many thanks.
Ps: i'm using xcode, the latest cocos2d-x release and the iPhone simulator
Edit:
Using breakpoints i checked where things go bad while loading the tilemap.
on the line tileMap = CCTMXTiledMap::create(map);
my variable map is still fine
but on line tileMap->setAnchorPoint(ccp(0,0));
it is suddenly corrupted (most of the time)
It sounds like you're returning a char* string created on the stack, which means the memory may or may not be corrupted, depending on circumstances, moon phases, and what not.
So the question is: How is getLevel defined and what does it do (post the code)?
If you do something like this:
const char* LevelManager::getLevel(int level)
{
char* levelName = "default.tmx";
return levelName;
}
…then that's going to be the culprit. The levelName variable is created on the stack, no memory (on the heap) is allocated for it. The levelName variable and the memory it points to become invalid as soon as the method returns.
Hence when the method leaves this area of memory where levelName points to can be allocated by other parts of the program or other method's stack memory. Whatever is in that area of memory may still be the string, or it may be (partially) overridden by other bits and bytes.
PS: Your exception handling code is …. well it shows a lack of understanding what exception handling does, how to use it and especially when. I hope these are just remnants of trying to get to the bottom of the issue, otherwise get rid of it. I recommend reading a tutorial and introductions on C++ exception handling if you want to continue to use exceptions. Especially something like (map != NULL) should be an assertion, not an exception.
I fixed it.
const char* was to blame.
When returning my map as a char * it worked flawless.
const char *levelFileName = level.attribute("file").value();
char *levelChar = new char[strlen(levelFileName) + 1];
std:: strcpy (levelChar, levelFileName);
return levelChar;
Thats how i now return the map.

Memory leaks after using typeinfo::name()

I have a program in which, partly for informational logging, I output the names of some classes as they are used (specifically I add an entry to a log saying along the lines of Messages::CSomeClass transmitted to 127.0.0.1). I do this with code similar to the following:
std::string getMessageName(void) const {
return std::string(typeid(*this).name());
}
And yes, before anyone points it out, I realise that the output of typeinfo::name is implementation-specific.
According to MSDN
The type_info::name member function returns a const char* to a null-terminated string representing the human-readable name of the type. The memory pointed to is cached and should never be directly deallocated.
However, when I exit my program in the debugger, any "new" use of typeinfo::name() shows up as a memory leak. If I output the information for 2 classes, I get 2 memory leaks, and so on. This hints that the cached data is never being freed.
While this is not a major issue, it looks messy, and after a long debugging session it could easily hide genuine memory leaks.
I have looked around and found some useful information (one SO answer gives some interesting information about how typeinfo may be implemented), but I'm wondering if this memory should normally be freed by the system, or if there is something i can do to "not notice" the leaks when debugging.
I do have a back-up plan, which is to code the getMessageName method myself and not rely on typeinfo::name, but I'd like to know anyway if there's something I've missed.
Another solution is to correct the underlying problem. This is not really a memory leak, just a false report. The memory blocks allocated to the tyepinfo() and the name() string are assigned the wrong block type. It is probably not a good idea to "free" this memory, since an attempt will be made by the CRT to free it again. The good news is this was finally fixed in VS2012 (_MSC_VER 1700+).
Since this only applies to _DEBUG builds, the following may be a safer solution. The function _FixTypeInfoBlockUse() should be called as mentioned above just before exiting the module entry point (main, WinMain, etc.).
#if defined(_DEBUG) && (_MSC_VER >= 1000 && _MSC_VER <= 1699)
//
// Debug memory block header:
// o Borrowed from the Microsoft CRT to fix the false "memory leak" report
// when using typeinfo 'name' accessor in a _DEBUG build of the library.
//
struct _CrtMemBlockHeader
{
struct _CrtMemBlockHeader * pBlockHeaderNext;
struct _CrtMemBlockHeader * pBlockHeaderPrev;
char * szFileName;
int nLine;
#ifdef _WIN64
int nBlockUse;
size_t nDataSize;
#else
size_t nDataSize;
int nBlockUse;
#endif
long lRequest;
unsigned char gap[4];
};
static void __cdecl _FixTypeInfoBlockUse(void)
{
__type_info_node* pNode = __type_info_root_node._Next;
while(pNode != NULL)
{
__type_info_node* pNext = pNode->_Next;
(((_CrtMemBlockHeader*)pNode) - 1)->nBlockUse = _CRT_BLOCK;
if (pNode->_MemPtr != NULL)
(((_CrtMemBlockHeader*)pNode->_MemPtr) - 1)->nBlockUse = _CRT_BLOCK;
pNode = pNext;
}
}
#endif//defined(_DEBUG) && (_MSC_VER >= 1000 && _MSC_VER <= 1699)
I've just stumbled upon this issue trying to clean the log of VLD. Yes, this is a known bug, which is fixed in VC11 only. It exists in previous versions of MSVC including 2010. This bug appears only if you use MFC. If you use MFC as DLL instead of static library, the memory leak will still exist, but won't be detected.
There is a global cache of type_info names and it is not cleared (the excerpt from <typeinfo>):
struct __type_info_node {
void *_MemPtr;
__type_info_node* _Next;
};
extern __type_info_node __type_info_root_node;
The idea is to clear this cache. This function works for me:
#include <typeinfo>
void clear_type_info_cache()
{
__type_info_node* & node = __type_info_root_node._Next;
while(node)
{
if (node->_MemPtr)
{
delete node->_MemPtr;
}
__type_info_node* tempNode = node;
node = node->_Next;
delete tempNode;
}
}
Call clear_type_info_cache() before exit. You can register it with atexit
#include <cstdlib>
int WinMain(...)
{
atexit(&clear_type_info_cache);
...
}
or call it immediately before leaving WinMain
struct dummy_scope_exit
{
typedef void (*Fun)();
dummy_scope_exit(Fun f) : m_f(f) {}
~dummy_scope_exit() { m_f(); }
Fun m_f;
};
int WinMain(...)
{
dummy_scope_exit cleaner = &clear_type_info_cache;
...
}
As pointed out by Chris Parton in the comments, this appears to be a known bug, at least with the version of compiler I am using - upgrading to VC11 would correct the issue, if I were able to upgrade.
Attempting to delete the output of typeinfo::name() partially works:
std::string getMessageName(void) const
{
std::string typeStr(typeid(*this).name());
delete (typeid(*this).name());
return typeStr;
}
However there are still some memory leaks - I just noticed that previously I appeared to be getting two leaks per call (perhaps due to the classes being inside a namespace?). Using the above version of code, this went down to one leak per call.
Another solution that appears to work is to link in the dynamic version of the MFC libraries (yes, I'm using MFC, don't judge me), rather than the static version.
VS stores type info in a singly-linked list. The header of this list is accessible by an opaque structure accessible by name __type_info_root_node. Actually it is a SLIST_HEADER structure.
Win32 API has a set of concurrency-safe function to work with such structures.
To fix memory leaks report In your case you need to delete all nodes of this list.
#include <Windows.h>
#include <typeinfo>
#include <vld.h>
void ClearTypeinfoCache()
{
#ifdef _DEBUG
while (auto entry = InterlockedPopEntrySList(reinterpret_cast<PSLIST_HEADER>(&__type_info_root_node)))
{
free(entry);
}
#endif
}
int main()
{
atexit(ClearTypeinfoCache);
return 0;
}
Updated: VLD 2.5.1 does not report memory leaks on type_info::name() in VS2015 Update 3.

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.