Custom data gathering class crashes user program

Hi, I’m having a bit of trouble with a class I wrote, it appears to be crashing the user program as soon a VxWorks attempts to launch it. I’m not sure what part of it is crashing it either, but i have tried commenting out everything in its Get(); member so the only thing left was a return 0; statement to see if that was the problem, so I’m assuming its the constructor.

The way the code is meant to work is gather bits from three dip switches, and then translate that binary sequence into a more usable decimal number.

this is how I have been calling the constructor and destructor. I have tried not using an object pointer, but i still had the same problem.


switchbox *box = new switchbox(10, 9, 8);
int mode2= box->Get(); 
box->~switchbox();

and this is the class:


class switchbox {
public:
	int Get();
	switchbox(int port1, int port2, int port3);
	virtual ~switchbox();
private:
	bool port1;
	bool port2;
	bool port3;
	int mode;
	int bin2dec(bool bit[3]);
	bool readPorts(int port);
};

 bool switchbox::readPorts(int port)//this gets the input values from the program switchbox
{
	DigitalInput *digital = new DigitalInput(port);
	bool port_ = false;
	port_ = digital->Get();
	digital->~DigitalInput();
	return port_;
}

 int switchbox::bin2dec(bool bit[3])//this is a 3 bit binary to decimal converter. 
{ //to be used for the program switchbox.
	int num=0;

	if (bit[1]) {
		num=num+1;
	}
	if (bit[2]){
		num=num+2;
	}
	if (bit[3]) {
		num=num+4;
	}
  return mode = num; //member functions can access private data, doing this to hopefully not need another int.
}


 int switchbox::Get(){
	 bool bit[3];
	for( int i=0; i<=3; i++){
		bit* = switchbox::readPorts(i);
	}
	bin2dec(bit);
	
	return mode;
}



thanks to anyone who can help with this!*

Well, you don’t post the constructor, so we can’t help you with that. However, there are a couple things I noticed:

// NEVER, EVER call the destructor like 
box->~switchbox()
//It's much better to use:
delete box;

// readports can be simplified: 
bool switchbox::readPorts(int port)//this gets the input values from the program switchbox
{
	return DigitalInput(port).Get();
}

// bin2dec is accessing invalid array boundries:
// You have an array[3], but you access 1 2 3.
// Change those to 0 1 2
// Actually, the entire function can be simplified:
int switchbox::bin2dec(bool bit[3])
{
	return (bit[0] | (bit[1] << 1) | (bit[2] << 2));
}

// The for loop in switchbox::Get() will get four bools, but you're trying to store them in an array of 3.

ok, ill try that. but i have never seen the left shift operator used like this before


int switchbox::bin2dec(bool bit[3])
{
	return (bit[0] | (bit[1] << 1) | (bit[2] << 2));
}

can you explain how you are using the bitwise or as well?

We’ll assume that the value you want to return is from 0-7.
This would take up three bits (unsigned) out of a byte.
bit[0] takes up the “lowest” bit, and bit[2] takes up the “highest” (going by the code you posted). If we want to arrange the bits XYZ, then bit[2] = X, bit[1] = Y, and bit[0]=Z.
The expression bit[0] evaluates to 00Z.
The expression bit[1] also evaluates to 00Y, but (bit[1]<<1) becomes 0Y0.
The expression bit[2] is 00X, but (bit[2]<<2) is X00, because it’s shifted two bits to the left.
So now we have:
00Z
0Y0
X00
all as individual bits. To put those together, we just bitwise-OR them to get XYZ. The X bit is equal to 4 if it’s true, the Y bit is equal to 2 if it’s true, and the Z bit is 1 if it’s true. An important thing to know is that (x<<n) == (x * pow(2,n)), ignoring two’s complement.

This looks awefully complex for getting the value of a few digital input bits. We have a BCD switch that is connected to the digital input channels 11, 12, 13 and 14. We have one statement to get all the digtal input bits and a macro to massage the bits to the right value.


#define BCDSwitchValue(x)       (((~(x)) >> 2) & 0x0f)
UINT32 startingPosition = BCDSwitchValue(m_digitalIn->GetDIO());

Thanks for explaining that. As for marcos, im not exactly comfortable with them yet, that class i asked for help on is the first one i have ever written ( im usually a proceedural programmer)

To explain the macro: ~(x) is to flip the bits of the value X (1’s complement). For example, if X was 0110, then ~(x) will be 1001. This is so that a switch, when turned ON, shorts the digital channel to ground reading a 0. So ON becomes zero, and OFF becomes 1. For our BCD swtich, we need ON as 1 and OFF as 0, so we use ~(x) to flip the bits. For the digital input channels, channel 1 is actually bit 15, channel 2 bit 14, channel 3 bit 13 …, channel 11 is bit 5, channel 12 is bit 4, channel 13 is bit 3 and channel 14 is bit 2. So to right justify bit 11-14, we need to shift it right 2 bits. And of course finally mask it off so we only care about the least significant 4 bits.


#define BCDSwitchValue(x)       (((~(x)) >> 2) & 0x0f)

BTW, the single statement and the macro are totally procedural, no class required :slight_smile: