Derived Class Array not Formed - c++

I am facing a problem while creating an array of derived class objects, and I can not find any explanation of this problem. The problem is the following:
I have an abstract base class RDMonitorBase and a derived class RDMonitorHashTable.
In another class RDMonitorPool I have the variable RDMonitorBase * m_rd_monitors.
In RDMonitorPool constructor I am creating an array of RDMonitorHashTable objects (using new)
and assigning them to m_rd_monitors.
Immediately after the construction, only the even number indexed RDMonitorHashTable objects are properly formed. The objects with odd numbered index have garbage in the member variables. I have no idea why this is happening.
The code and the GDB output on a breakpoint immediately after the construction are given below:
Relevant parts of the RDMonitorBase and RDMonitorHashTable classes are as follows. I have a virtual Access() method in Base which is not implemented in the derived, and a pure virtual RecordDistance() method. Access() calls the RecordDistance() method. This should be okay I think, a similar structure worked when I created simple examples.
class RDMonitorBase {
public:
RDMonitorBase();
virtual void StartMonitoring(const physical_address_t& target_address, const int core_id);
virtual Index Access(const physical_address_t& address, const int core_id);
bool IsActive() { return m_active; }
static const Index TRACKING_NOT_COMPLETE = -1;
protected:
virtual void RecordDistance(const physical_address_t& address) = 0;
const Index m_maximum_distance;
bool m_active;
physical_address_t m_target_address;
Index m_distance;
int m_core_id;
};
class RDMonitorHashTable: public RDMonitorBase {
public:
RDMonitorHashTable();
virtual void StartMonitoring(const physical_address_t& target_address,
const int core_id);
protected:
virtual void RecordDistance(const physical_address_t& address);
std::tr1::unordered_set<physical_address_t> m_address_set;
};
RDMonitorBase::RDMonitorBase():
m_maximum_distance(32),
m_active(false),
m_target_address(0),
m_distance(0),
m_core_id(-1) { ; }
Index RDMonitorBase::Access(const physical_address_t& address,
const int core_id) {
// ... some code
RecordDistance(address);
//... some other code
return m_distance;
}
RDMonitorHashTable::RDMonitorHashTable()
:RDMonitorBase() { ; }
void RDMonitorHashTable::RecordDistance(const physical_address_t& address) {
m_address_set.insert(address);
m_distance = m_address_set.size();
}
Now in the RDMonitorPool class constructor, the following is basically executed:
RDMonitorBase * m_rd_monitors = new (std::nothrow) RDMonitorHashTable[4096];
After this line executes, when I try to print the objects in gdb, I get this:
(gdb) print *(m_rd_monitors + 0)
$2 = {_vptr.RDMonitorBase = 0x7ffd93cacc90, static TRACKING_NOT_COMPLETE = -1, m_maximum_distance = 32, m_active = false, m_target_address = 0, m_distance = 0, m_core_id = -1}
(gdb) print *(m_rd_monitors + 1)
$3 = {_vptr.RDMonitorBase = 0x1, static TRACKING_NOT_COMPLETE = -1, m_maximum_distance = 68540736, m_active = 11, m_target_address = 0, m_distance = 4611686019492741120, m_core_id = 11}
(gdb) print *(m_rd_monitors + 2)
$4 = {_vptr.RDMonitorBase = 0x7ffd93cacc90, static TRACKING_NOT_COMPLETE = -1, m_maximum_distance = 32, m_active = false, m_target_address = 0, m_distance = 0, m_core_id = -1}
(gdb) print *(m_rd_monitors + 3)
warning: can't find linker symbol for virtual table for `RDMonitorBase' value
$5 = warning: can't find linker symbol for virtual table for `RDMonitorBase' value
{_vptr.RDMonitorBase = 0x7ffda46b3e98, static TRACKING_NOT_COMPLETE = -1, m_maximum_distance = 68566480, m_active = 11, m_target_address = 0, m_distance = 4611686019492741120, m_core_id = 11}
So the even-indexed values have the proper values that are assigned in the constructor (for example 32 for m_maximum_distance). But the odd-index objexxts have garbage in m_maximum_distance and other members.
I will be extremely thankful if anybody can shed some light on why this is happening. Thanks!

Your problem is addressed here: Base pointer to array of derived objects
The problem is that the array is of type RDMonitorBase, so when you try to access any of its positions, the compiler calculates the offset according to RDMonitorBase instead of RDMonitorHashTable, effectively dereferencing the memory at the wrong point and thus slicing up the actual object which is of a different type. From the point your program access any position of that array, its bahavior becomes undefined.
The most straightforward alternative would be to use an array of pointers to the base type and assign an object of the derived class dynamicaly constructed to each of them.
RDMonitorBase* m_rd_monitors[4096];
for(std::size_t i = 0; i < 4096; ++i)
m_rd_monitors[i] = new (std::nothrow) RDMonitorHashTable;

Related

Create a lookup table for array of classes in C++/Arduino

I have multiple types of classes.
Each type has an array and an index in the array.
If an outside function knows only a string ID of a class and wants to use it's public function,
it must search for that particular class by ID in it's array.
This is really inefficient.
All my classes created at runtime and a function which creates it, puts it into an array.
I want to create a lookup table of some sort for this when the classes are created, so any outside
function if wants to use one class it does not have to for loop on the class's array and check each ID if it matches but to be able to reach the class by some struct or array.
Here how it is done now:
#define MAX_ONE_TYPES 20
int createdOneTypesCounter = 0;
// Create one type of classes in one for loop and put it into an array.
// We must keep track of the index because a class can be created later
// at runtime so we must keep increasing the index. I don't check for max index now...
// oneTypes is a JSON OBJECT
for (JsonPair oneTypeRef: oneTypes) {
const char* oneTypeID = oneTypeRef.key().c_str();
JsonObject oneTypeOptions = oneTypes[oneTypeID];
oneTypeClasses[createdOneTypesCounter ] = new oneTypeClass(oneTypeOptions);
createdOneTypesCounter++;
}
class oneTypeClass{
private:
// using an external ram for this kinda stuffs.
const size_t IDS_AND_NAMES_SIZE = 500;
const char * id = (char *) ps_malloc (IDS_AND_NAMES_SIZE * sizeof (char));
public:
thermHandler(JsonObject options){
// She got an ID on creation.
id = strdup(options["id"]);
}
void setModes(boolean mode){
// set some mode...
}
boolean isMyID(const char* packetID){
if( strcmp(id, packetID) == 0 ){return true;}
return false;
}
};
oneTypeClass* oneTypeClasses[MAX_ONE_TYPES] EXT_RAM_ATTR;
// Here comes an outside function. Wants to set a boolean in a class with specific ID.
static const inline void setOneTypeMode(JsonObject packet){
for(int i = 0; i < MAX_ONE_TYPES; i++){
if(oneTypeClasses[i] != NULL && oneTypeClasses[i]->isMyID(packet["id"])){
oneTypeClasses[i]->setModes(packet["mode"]);
break;
}
}
}
And here is my problem. I must search for a class by ID every time some outside function wants to do something with one of the classes.
I don't know how would i do it.
In JS i would create an object for a lookup table and every time a class is created i would put it's ID for the key and it's index to the value like this:
var oneTypeClass_Lookup{
"CLASS ID STRING" : "CLASS INDEX IN ARRAY"
};
//And a function would do it like this:
static const inline void setOneTypeMode(JsonObject packet){
int myClassIndex = oneTypeClass_Lookup[ packet["id"] ];
oneTypeClasses[myClassIndex]->setModes(packet["mode"]);
}
I'm doing this for "mass operation":
static const inline int getOneTypeClassIndex(const char* packetID){
for(int i = 0; i < MAX_THERMS; i++){
if(oneTypeClasses[i] != NULL && oneTypeClasses[i]->isMyID(packetID)){
return i;
}
}
return -1;
}
static const inline void setThing(int newThing, const char* packetID){
int index = getOneTypeClassIndex(packetID);
if( index > -1 ){
oneTypeClasses[index]->setNewThing(newThing);
}
}
static const inline void setThing_Two(int newThing, const char* packetID){
int index = getOneTypeClassIndex(packetID);
if( index > -1 ){
oneTypeClasses[index]->setNewThing(newThing);
}
}
But i can't do this in C or Arduino C++. I hope i was clear.
UI: Class id consist of numbers and characrers. The id can never start with a number. Example: "v_kw62ffss_xg0syjlvrokbxciv65a8y"

Cast an object that is pointed by an iterator

I have this multiset container:
multiset<IMidiMsgExt, IMidiMsgExtComp> queuedNotes;
IMidiMsgExt is a struct I've created myself (I need it for one additional property, mTick) that extend IMidiMsg :
struct IMidiMsgExt : public IMidiMsg
{
IMidiMsgExt() {
}
double mTick = 0.;
void IMidiMsgExt::MakeNoteOnMsg(int noteNumber, int velocity, int offset, double tick, int channel)
{
Clear();
mStatus = channel | (kNoteOn << 4);
mData1 = noteNumber;
mData2 = velocity;
mOffset = offset;
mTick = tick;
}
void IMidiMsgExt::MakeNoteOffMsg(int noteNumber, int offset, double tick, int channel)
{
Clear();
mStatus = channel | (kNoteOff << 4);
mData1 = noteNumber;
mOffset = offset;
mTick = tick;
}
void IMidiMsgExt::Clear()
{
mOffset = 0;
mStatus = mData1 = mData2 = 0;
mTick = 0.;
}
};
Next: I store in that queuedNotes multiset some IMidiMsgExt objects, with:
IMidiMsgExt* noteOff = new IMidiMsgExt;
noteOff->MakeNoteOffMsg(57, 0, tickSize * 111, 0);
queuedNotes.insert(*noteOff);
Now, I need to use a function called SendMidiMsg(IMidiMsg* pMsg) (that takes IMidiMsg type as input) sending my object IMidiMsgExt to it.
I extract the first object from my list to an iterator:
auto midiMessage = queuedNotes.begin();
But when I try to cast it and use SendMidiMsg:
SendMidiMsg((IMidiMsgExt*)midiMessage);
it says no suitable conversion function from "std::_Tree_const_iterator<std::_Tree_val<std::_Tree_simple_types<IMidiMsgExt>>>" to "IMidiMsg *" exists
Where am I wrong? Should I use dynamic casting?
auto midiMessage = queuedNotes.begin();
midiMessage is of type std::multiset::iterator. And it is not convertable to your type IMidiMsgExt. Iterator is an object that behaves similarly to a pointer, so you can use dereference operator (*) to get the object that it "points to". You also don't need to cast derived object to its base, that is done implicitly. All you need to do is get the address of where the iterator "points to" to get a pointer to IMidiMsgExt:
SendMidiMsg(&*midiMessage);
A quick break down of &*midiMessage:
variable - type
midiMessage - std::multiset::iterator
*midiMessage - IMidiMsgExt
&*midiMessage - IMidiMsgExt*
Edit:
About your const_iterator error. std::multiset::begin() is supposed to always return const_iterator. Your function SendMidiMsg() wants a non const pointer - it is saying it wants to edit the message. multiset does not allow changing the elements.
You can copy the message and then call SendMidiMsg(). If you don't need the message inside the container anymore, you can also erase it afterwards.
auto msg = *midiMessage;
SendMidiMsg(&msg);
queuedNotes.erase(midiMessage);
Note: It seems like you have a memory leak in the program. You create messages with new and I don't see any calls to delete, to release the memory.
IMidiMsgExt* noteOff = new IMidiMsgExt;
noteOff->MakeNoteOffMsg(57, 0, tickSize * 111, 0);
queuedNotes.insert(*noteOff);

Code requires too much memory

I'm porting some code to another structure:
class EnvironObject
{
protected:
vector<float> mX, mY, mXSpeed, mYSpeed;
int mMaxObjects;
public:
virtual void init(int maxObjects);
virtual void setLimit(int limit);
virtual int getLimit();
virtual void update(float arg) = 0;
};
void EnvironObject::setLimit(int limit)
{
mMaxObjects = limit;
mX.resize(limit, 0); mY.resize(limit, 0);
mXSpeed.resize(limit, 0); mY.resize(limit, 0);
}
int EnvironObject::getLimit()
{
return mMaxObjects;
}
void EnvironObject::init(int maxObjects)
{
mX = mY = mXSpeed = mYSpeed = std::vector<float>(mMaxObjects);
fill(mX.begin(), mX.end(), 0);
fill(mY.begin(), mY.end(), 0);
fill(mXSpeed.begin(), mXSpeed.end(), 0);
fill(mYSpeed.begin(), mYSpeed.end(), 0);
/*mX.reserve(mMaxObjects * 1.5); mY.reserve(mMaxObjects * 1.5);
mXSpeed.reserve(mMaxObjects * 1.5); mYSpeed.reserve(mMaxObjects * 1.5);*/
mMaxObjects = maxObjects;
}
This is some basic class, now it's usage:
class Rain : public EnvironObject
{
public:
Rain(int maxDrops = 150);
void update(float windPower);
};
Rain::Rain(int maxDrops)
{
srand(time(NULL));
IEnvironObject::init(maxDrops);
}
void Rain::update(float windPower)
{
for (int i=0; i < mMaxObjects; i++)
{
mX[i] += mXSpeed[i];
mY[i] += mYSpeed[i];
mXSpeed[i] += windPower;
mYSpeed[i] += G;
// Drawing
}
}
The objects Rain creates with default constructor (so, each array is 150 elements size) and then I'm calling setLimit(50).
The problem is that code fails almost each running with exception:
terminate called after throwing an instance of 'std::bad_alloc'
And sometimes it segfaults at line:
mY[i] += mYSpeed[i];
I can't image what could it be, because the code is old and it worked. The new one is only base class.
And when I'm looking at RAM usage when starting app, I see almost +600 mb!
Look again at that function of yours:
void EnvironObject::init(int maxObjects)
{
mX = mY = mXSpeed = mYSpeed = std::vector<float>(mMaxObjects);
// ^
// ...
mMaxObjects = maxObjects;
}
You're using a not yet initialized variable.
A big problem with your class is that you are doing what's called two-phase construction. Your class EnvironObject has a compiler-supplied default constructor that creates an object with random values for all POD types (mMaxObjects). Users then need to call the init() method to really initialize the object. But that's what constructors are there for!
void EnvironObject::EnvironObject(int maxObjects)
: mMaxObjects(maxObjects)
, mX(maxObjects), mY(maxObjects), mXSpeed(maxObjects), mYSpeed(maxObjects)
{
/* these aren't necessary, std::vector automatically does this
fill(mX.begin(), mX.end(), 0);
fill(mY.begin(), mY.end(), 0);
fill(mXSpeed.begin(), mXSpeed.end(), 0);
fill(mYSpeed.begin(), mYSpeed.end(), 0);
*/
}
Derived classes can then use this constructor:
Rain::Rain(int maxDrops)
: EnvironObject(maxDrops)
{
srand(time(NULL));
}
Regarding this crash in the subscription mY[i] += mYSpeed[i]:
This might happen when you are calling this function through a pointer that's pointing to nowhere.
You're using mMaxObjects in init() before initializing it. So it has a random value.
void EnvironObject::init(int maxObjects)
{
mX = mY = mXSpeed = mYSpeed = std::vector<float>(mMaxObjects); // you mean maxObjects here
I think you want to replace
void EnvironObject::init(int maxObjects)
{
mX = mY = mXSpeed = mYSpeed = std::vector<float>(mMaxObjects);
with
void EnvironObject::init(int maxObjects)
{
mX = mY = mXSpeed = mYSpeed = std::vector<float>(maxObjects);
Notice the replacement of mMaxObject to maxObjects in the vector creation.
One comment, though it won't likely fix your memory error, is that since the fields mX, mY, mXSpeed, and mYSpeed seem related and the vectors are all the same size, you should consider merging them into one structure with four members, and having a single vector containing several of those structure instances.

Inherited variables are not reading correctly when using bitwise comparisons

I have a few classes set up for a game, with XMapObject as the base, and XEntity, XEnviron, and XItem inheriting it.
MapObjects have a number of flags, one of them being MAPOBJECT_SOLID. My problem is that XEntity is the only class that correctly detects MAPOBJECT_SOLID. Both Items are Environs are always considered solid by the game, regardless of the flag's state. What is important is that Environs and Item should almost never be solid.
Each class has a very basic preliminary constructor, just initializing all varibles to zero or NULL. During the CreateX() phase, Objects are linked into the map, set into a linked linked list.
Both XItem and XEnviron are a tad sloppy. They are both new, and in the middle or my debugging attempts.
Here are the relevent code samples:
XMapObject:
#define MAPOBJECT_ACTIVE 1
#define MAPOBJECT_RENDER 2
#define MAPOBJECT_SOLID 4
class XMapObject : public XObject
{
public:
Uint8 MapObjectType,Location[2],MapObjectFlags;
XMapObject *NextMapObject,*PrevMapObject;
XMapObject();
void CreateMapObject(Uint8 MapObjectType);
void SpawnMapObject(Uint8 MapObjectLocation[2]);
void RemoveMapObject();
void DeleteMapObject();
void MapObjectSetLocation(Uint8 Y,Uint8 X);
void MapObjectMapLink();
void MapObjectMapUnlink();
};
XMapObject::XMapObject()
{
MapObjectType = 0;
Location[0] = 0;
Location[1] = 1;
NextMapObject = NULL;
PrevMapObject = NULL;
}
void XMapObject::CreateMapObject(Uint8 Type)
{
MapObjectType = Type;
}
void XMapObject::SpawnMapObject(Uint8 MapObjectLocation[2])
{
if(!(MapObjectFlags & MAPOBJECT_ACTIVE)) { MapObjectFlags += MAPOBJECT_ACTIVE; }
Location[0] = MapObjectLocation[0];
Location[1] = MapObjectLocation[1];
MapObjectMapLink();
}
XEntity:
XEntity *StartEntity = NULL,*EndEntity = NULL;
class XEntity : public XMapObject
{
public:
Uint8 Health,EntityFlags;
float Speed,Time;
XEntity *NextEntity,*PrevEntity;
XItem *IventoryList;
XEntity();
void CreateEntity(Uint8 EntityType,Uint8 EntityLocation[2]);
void DeleteEntity();
void EntityLink();
void EntityUnlink();
Uint8 MoveEntity(Uint8 YOffset,Uint8 XOffset);
};
XEntity::XEntity()
{
Health = 0;
Speed = 0;
Time = 1.0;
EntityFlags = 0;
NextEntity = NULL;
PrevEntity = NULL;
IventoryList = NULL;
}
void XEntity::CreateEntity(Uint8 EntityType,Uint8 EntityLocation[2])
{
CreateMapObject(EntityType);
SpawnMapObject(EntityLocation);
if(!(MapObjectFlags & MAPOBJECT_SOLID) { MapObjectFlags += MAPOBJECT_SOLID; }
EntityFlags = ENTITY_CLIPPING;
Time = 1.0;
Speed = 1.0;
EntityLink();
}
void XEntity::EntityLink()
{
if(StartEntity == NULL)
{
StartEntity = this;
PrevEntity = NULL;
NextEntity = NULL;
}
else
{
EndEntity->NextEntity = this;
}
EndEntity = this;
}
XEnviron:
class XEnviron : public XMapObject
{
public:
Uint8 Effect,TimeOut;
void CreateEnviron(Uint8 Type,Uint8 Y,Uint8 X,Uint8 TimeOut);
};
void XEnviron::CreateEnviron(Uint8 EnvironType,Uint8 Y,Uint8 X,Uint8 TimeOut)
{
CreateMapObject(EnvironType);
Location[0] = Y;
Location[1] = X;
SpawnMapObject(Location);
XTile *Tile = GetTile(Y,X);
Tile->Environ = this;
MapObjectFlags = MAPOBJECT_ACTIVE + MAPOBJECT_SOLID;
printf("%i\n",MapObjectFlags);
}
XItem:
class XItem : public XMapObject
{
public:
void CreateItem(Uint8 Type,Uint8 Y,Uint8 X);
};
void XItem::CreateItem(Uint8 Type,Uint8 Y,Uint8 X)
{
CreateMapObject(Type);
Location[0] = Y;
Location[1] = X;
SpawnMapObject(Location);
}
And lastly, the entity move code. Only entities are capable of moving themselves.
Uint8 XEntity::MoveEntity(Uint8 YOffset,Uint8 XOffset)
{
Uint8
NewY = Location[0] + YOffset,
NewX = Location[1] + XOffset;
if((NewY >= 0 && NewY < MAPY) && (NewX >= 0 && NewX < MAPX))
{
XTile *Tile = GetTile(NewY,NewX);
if(Tile->MapList != NULL)
{
XMapObject *MapObject = Tile->MapList;
while(MapObject != NULL)
{
if(MapObject->MapObjectFlags & MAPOBJECT_SOLID)
{
printf("solid\n");
return 0;
}
MapObject = MapObject->NextMapObject;
}
}
if(Tile->Flags & TILE_SOLID && EntityFlags & ENTITY_CLIPPING)
{
return 0;
}
this->MapObjectSetLocation(NewY,NewX);
return 1;
}
return 0;
}
What is wierd, is that the bitwise operator always returns true when the MapObject is an Environ or an Item, but it works correctly for Entities. For debug I am using the printf "Solid", and also a printf containing the value of the flag for both Environs and Items.
Any help is greatly appreciated, as this is a major bug for the small game I am working on. I am also very new at Object Oriented programming, anything tips, suggestions and/or criticism are also welcome.
Your problem appears to be that you never initialize MapObjectFlags in any classes other than XEnviron so, as a basic type, it will have an unspecified value in XItem, XEntity and other XMapObject derived objects. I suggest that, as a member of XMapObject you explicitly initialize it to a known value.
As a rule, it is generally a good idea to ensure that all members of basic type are explicitly initialized in the initializer list of every constructor that you define.
e.g.
XMapObject()
: MapObjectFlags(0)
, // ... other initializers
{
// Other initializations
}
You can't (legally) be calling XEntity::MoveEntity on a MapObject or Environ because they don't have such a method. If you're using static_cast to change your object pointer into an XEntity so you can call MoveEntity on it, then you really have no guarantees about how the bit operation will work. In some implementations, things may appear to work in MoveEntity, but what's actually happening is it's interpreting the other object's memory as an XEntity. When it tries to access the offset where it believes MapObjectFlags exists, it's not actually there and always has that bit set to 1.
I figured out the problem earlier today - It didn't have any relation to OO programming, inheritance, or bitwise; it was a simple scope error.
The problem was in the fact that during my quick test to get an Environ in game, I declared the new variable inside of the control switch sequence, so the next time any control was used, the Environ would act in unpredictable ways.
switch(Event.key.keysym.sym)
{
...
case SDLK_c: { XEnviron Environ; Environ.InitEnviron(...); }
...
}

Function has corrupt return value

I have a situation in Visual C++ 2008 that I have not seen before. I have a class with 4 STL objects (list and vector to be precise) and integers.
It has a method:
inline int id() { return m_id; }
The return value from this method is corrupt, and I have no idea why.
debugger screenshot http://img687.imageshack.us/img687/6728/returnvalue.png
I'd like to believe its a stack smash, but as far as I know, I have no buffer over-runs or allocation issues.
Some more observations
Here's something that puts me off. The debugger prints right values in the place mentioned // wrong ID.
m_header = new DnsHeader();
assert(_CrtCheckMemory());
if (m_header->init(bytes, size))
{
eprintf("0The header ID is %d\n", m_header->id()); // wrong ID!!!
inside m_header->init()
m_qdcount = ntohs(h->qdcount);
m_ancount = ntohs(h->ancount);
m_nscount = ntohs(h->nscount);
m_arcount = ntohs(h->arcount);
eprintf("The details are %d,%d,%d,%d\n", m_qdcount, m_ancount, m_nscount, m_arcount);
// copy the flags
// this doesn't work with a bitfield struct :(
// memcpy(&m_flags, bytes + 2, sizeof(m_flags));
//unpack_flags(bytes + 2); //TODO
m_init = true;
}
eprintf("Assigning an id of %d\n", m_id); // Correct ID.
return
m_header->id() is an inline function in the header file
inline int id() { return m_id; }
I don't really know how best to post the code snippets I have , but here's my best shot at it. Please do let me know if they are insufficient:
Class DnsHeader has an object m_header inside DnsPacket.
Main body:
DnsPacket *p ;
p = new DnsPacket(r);
assert (_CrtCheckMemory());
p->add_bytes(buf, r); // add bytes to a vector m_bytes inside DnsPacket
if (p->parse())
{
read_packet(sin, *p);
}
p->parse:
size_t size = m_bytes.size(); // m_bytes is a vector
unsigned char *bytes = new u_char[m_bytes.size()];
copy(m_bytes.begin(), m_bytes.end(), bytes);
m_header = new DnsHeader();
eprintf("m_header allocated at %x\n", m_header);
assert(_CrtCheckMemory());
if (m_header->init(bytes, size)) // just set the ID and a bunch of other ints here.
{
size_t pos = DnsHeader::SIZE; // const int
if (pos != size)
; // XXX perhaps generate a warning about extraneous data?
if (ok)
m_parsed = true;
}
else
{
m_parsed = false;
}
if (!ok) {
m_parsed = false;
}
return m_parsed;
}
read_packet:
DnsHeader& h = p.header();
eprintf("The header ID is %d\n", h.id()); // ID is wrong here
...
DnsHeader constructor:
m_id = -1;
m_qdcount = m_ancount = m_nscount = m_arcount = 0;
memset(&m_flags, 0, sizeof(m_flags)); // m_flags is a struct
m_flags.rd = 1;
p.header():
return *m_header;
m_header->init: (u_char* bytes, int size)
header_fmt *h = (header_fmt *)bytes;
m_id = ntohs(h->id);
eprintf("Assigning an id of %d/%d\n", ntohs(h->id), m_id); // ID is correct here
m_qdcount = ntohs(h->qdcount);
m_ancount = ntohs(h->ancount);
m_nscount = ntohs(h->nscount);
m_arcount = ntohs(h->arcount);
You seem to be using a pointer to an invalid class somehow. The return value shown is the value that VS usually uses to initialize memory with:
2^32 - 842150451 = 0xCDCDCDCD
You probably have not initialized the class that this function is a member of.
Without seeing more of the code in context.. it might be that the m_id is out of the scope you expect it to be in.
Reinstalled VC++. That fixed everything.
Thank you for your time and support everybody! :) Appreciate it!