Constructor not called if a default param is supplied?

Started by
16 comments, last by Zahlman 18 years, 9 months ago
Quote:Original post by Zahlman
memset and ZeroMemory, and everything else along similar lines, are dangerous things to be using with class instances (only really acceptable with POD-types, and even then, usually needlessly tricky). Just write a proper default ctor for Value instead; it will be called for each instance when the array is allocated. Better yet, use std::vector which among its other benefits is also able to separate memory allocation from instance initialization, and will keep things running smoothly and efficiently for you behind the scenes :)


OMG, I'm so stupid. The memset() call was left from when I was using a long data-type. I didn't really think that this merited a vector, since I don't need to change the size of the array at any time other than the constructor.
Advertisement
I don't know how big a Value is, but if it's larger than a single byte, then memset(&m_pStates, 0, nStateCount); isn't right.

Actually, it isn't right anyway, you're taking the address of the pointer you silly person. Where is your pointer located? At the beginning of your class. That would explain why m_nCount ends up being 0, you're basically zeroing your class. And what ever is after it. Memory corruption, mmm, tasty.

Try memset(m_pStates, 0, nStateCount * sizeof *m_pStates);
Chess is played by three people. Two people play the game; the third provides moral support for the pawns. The object of the game is to kill your opponent by flinging captured pieces at his head. Since the only piece that can be killed is a pawn, the two armies agree to meet in a pawn-infested area (or even a pawn shop) and kill as many pawns as possible in the crossfire. If the game goes on for an hour, one player may legally attempt to gouge out the other player's eyes with his King.
You can test if it is called by creating a simple console application and doing something like this:
#include <iostream.h>class CTest {public: CTest(int arg=16) {  bob=arg;  cout << "Constructor called. arg=" << arg << "\n"; } ~CTest() {  cout << "Destructor called.\n"; } int bob;};int main() { //Test the different stuff CTest TestA, TestB(14); CTest *pTest=new CTest; //Parenthesis? (I forgot if they were necessary) delete pTest; //And put something here to prevent the program from automatically closing system("PAUSE");}

If the constructor with the default argument is called, then the output ought to look like this:
Constructor called. arg=16Constructor called. arg=14Constructor called. arg=16Destructor called.
If not:
Contructor called. arg=14.Destructor called.
EDIT: Was this already answered? *Prepares to feel stupid*
Projects:> Thacmus - CMS (PHP 5, MySQL)Paused:> dgi> MegaMan X Crossfire
Quote:Original post by smart_idiot
I don't know how big a Value is, but if it's larger than a single byte, then memset(&m_pStates, 0, nStateCount); isn't right.

Actually, it isn't right anyway, you're taking the address of the pointer you silly person. Where is your pointer located? At the beginning of your class. That would explain why m_nCount ends up being 0, you're basically zeroing your class. And what ever is after it. Memory corruption, mmm, tasty.

Try memset(m_pStates, 0, nStateCount * sizeof *m_pStates);

Quote:Original post by Programmer16
Okay I fixed it. I've never used memset() before and I was calling memset(&m_pStates, 0, nStates); (similiar to ZeroMemory()).


Yeah, I said that I was using it wrong (I'm used to using ZeroMemory()). Value has a std::string, int, bool, and a bool (*)() function pointer in it.

Quote:Original post by deadimp
EDIT: Was this already answered? *Prepares to feel stupid*


Yeah, this was already answered, but I'm the one that should feel stupid (I didn't even think of that.)
Quote:Original post by Programmer16
Yeah, I said that I was using it wrong (I'm used to using ZeroMemory()). Value has a std::string, int, bool, and a bool (*)() function pointer in it.


!!!

Then you should definitely not attempt to use memset, ZeroMemory or anything along those lines on a Value - at all - ever. You're trashing std::string internals like that - even an "empty" std::string might, depending on implementation, expect to contain a pointer to a valid memory allocation.

Actually, the default constructor for a Value would be equivalent to (AFAIK):

Value::Value() : theString(), theInt(0), theBool(false), theFunctionPointer(0) {}


Which means you probably don't really need to do anything at all.
Quote:Original post by deadimp
You can test if it is called by creating a simple console application and doing something like this:
*** Source Snippet Removed ***


#include <iostream.h> is non-standard and support is starting to be phased out on recent compilers, the standard header is <iostream> - no .h
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Quote:Original post by Zahlman
Quote:Original post by Programmer16
Yeah, I said that I was using it wrong (I'm used to using ZeroMemory()). Value has a std::string, int, bool, and a bool (*)() function pointer in it.


!!!

Then you should definitely not attempt to use memset, ZeroMemory or anything along those lines on a Value - at all - ever. You're trashing std::string internals like that - even an "empty" std::string might, depending on implementation, expect to contain a pointer to a valid memory allocation.

Actually, the default constructor for a Value would be equivalent to (AFAIK):

Value::Value() : theString(), theInt(0), theBool(false), theFunctionPointer(0) {}


Which means you probably don't really need to do anything at all.


I didn't think about that (silly me), but you're saying that it will automagically give me a constructor that will set all of my values to zero? Becuase it doesn't (unless I misunderstood what you're saying, which is quite possible since I just woke up.)

Edit:
Also, as I said, the call to memset was left over from when I was using longs. I didn't need to call memset() (or ZeroMemory()) because the default constructor for Value() does set them to their default values.
Quote:Original post by Programmer16
Quote:Original post by Zahlman
Actually, the default constructor for a Value would be equivalent to (AFAIK):

Value::Value() : theString(), theInt(0), theBool(false), theFunctionPointer(0) {}


Which means you probably don't really need to do anything at all.


I didn't think about that (silly me), but you're saying that it will automagically give me a constructor that will set all of my values to zero? Becuase it doesn't (unless I misunderstood what you're saying, which is quite possible since I just woke up.)


Er, I am quite probably mistaken on that count :) If so, just fill in the ctor illustrated above; it should do the trick.

This topic is closed to new replies.

Advertisement