tags:

views:

187

answers:

5

Hi

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 funtion:

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

+5  A: 

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)
  • ...
xtofl
I agree. In other words: Learn to use the debugger!
Adrian Grigore
... or at least print traces. Yet it is hard at the beginning to know where to look, what the usual suspects are.
David Rodríguez - dribeas
Yes, I would love to do that. Unfortuantely, the code is running on a development platform and here we do not have access to a debugger which makes things harder...
@Heinrich: (almost) no system is undebuggeable. When working on windows, e.g., you can 'remote debug' quite easily: start a small executable on the target machine, hook up to the debugger. (http://msdn.microsoft.com/en-us/library/y7f5zaaa.aspx)
xtofl
@Heinrich: and if that's not possible, do *printf-debugging*.
xtofl
+1 very good advice. It can also help if you put on a deerstalker hat, smoke a pipe filled with heroin and pace up and down your office, occasionally stopping to play the violin or give Watson a kiss.
Daniel Earwicker
@Earwicker: is this what you mean? http://upload.wikimedia.org/wikipedia/commons/thumb/c/ce/Sherlock_holmes_pipe_hat.jpg/250px-Sherlock_holmes_pipe_hat.jpg
xtofl
Yes, or alternatively if you can get a beige overcoat, transform yourself into Dim of the Yard! http://www.youtube.com/watch?v=txgnWWl8hgk
Daniel Earwicker
@xtofl : Totally agree. If all else fails then printf is your best friend
zebrabox
yes, I am using printf. End so I can see that the printf before the line "Hdr->SetCommand(cmd);" is still executed, but the printf after this line does not appear on the output screen anymore. So I assumed that this line is the evil of all!
@Heinrich: better assume that this line _triggers_ the evil. Now find out what the evil is, and why it is there. Put on your checkered deerstalker hat, as Earwicker says.
xtofl
Alright, found the problem. Null Pointer Exception as one would have expected. Problem solved now. Many thanks for all input of you guys.
A: 

It's probably SEGFAULTing. Check the pointers.

Aviral Dasgupta
A: 

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.

xtofl
An exception should be thrown if new fails to allocate memory, so no pointer will be ever returned.
sharptooth
@sharptooth: you're right. However, the OP commented that it _was_ a null pointer. How can this happen? Of course we can only guess the target architecture and it's exception support...
xtofl
A: 

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?

Shane
Its running on symbian
A: 

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.