tags:

views:

149

answers:

5

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

I'd like to believe its a stack smash, but as far as I know, I have no buffer over-runs or allocation issues.

+5  A: 

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
Mark Wilkins
Strictly speaking, VS will initialize heap allocated memory with 0xcd, heap freed memory with 0xdd, and stack memory with 0xcc.
MSN
Wow! Very quick reply! Appreciate it! I also get (seemingly) random values such as 1573768653 (0x5dcdcdcd), 1379021363 (0x52323233), 1389219277 (ox52cdcdcd).However, what puts me off is that when I change the function from inline to non-inline, all works well!
@tdsmapper: With the given information, I don't know for sure what is happening. If you can provide a short code example that demonstrates the problem, it might help. Someone will probably be able to spot the problem in seconds (at least that is what usually happens on stackoverflow).
Mark Wilkins
+1  A: 
  1. You probably have not initialized the class that this function is a member of.
  2. 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.
Harley Green
A: 

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 have to fix the formatting of this, it's unreadable. At least add newlines between statements.
Manuel
@Manuel: Apologies. I made a mistake with the formatting.
A: 

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; }
Yet ANOTHER observationeprintf("Assigning an id of %d/%d\n", m_id, id());prints the wrong ID when called with id(). May I conclude there's an issue with VC++ and inline functions in this case?
You should edit your question to include more information instead of posting an answer.
Roger Pate
A: 

Reinstalled VC++. That fixed everything.

Thank you for your time and support everybody! :) Appreciate it!