One of my weaknesses is effectively using chars in C++ which is what I am trying to do right now. I have a player class in my game and within the player class, I create a playerCard object which displays various information. This works fine for a single instance of the player object (i.e. Player player) but when I attempt to push_back a player object in to a vector it all goes wrong.
Basically, the program continues to run but the player doesn’t render to the screen. When I quit the program, I then get a breakpoint error when main tries to return MSG. The comment about the breakpoint reads:
/*
* If this ASSERT fails, a bad pointer has been passed in. It may be
* totally bogus, or it may have been allocated from another heap.
* The pointer MUST come from the 'local' heap.
*/
_ASSERTE(_CrtIsValidHeapPointer(pUserData));
I have located the error to here
strcat(nameCard, nameChar);
strcat(nameCard, genderChar);
strcat(nameCard, ageChar);
strcat(nameCard, cashHeldChar);
strcat(nameCard, productWantedChar);
within the playerCard class because when I comment this out, I do not get the error. Here is the full playerCard class (Again, it is messy and probably the wrong way for going about things but I am trying to get my head round using chars/strings etc)
#include “Headers.h”;
class Playercard{
private:
RECT textbox;
LPD3DXFONT font;
std::string nameStr;
std::string genderStr;
std::string ageStr;
std::string cashHeldStr;
std::string prodWantedStr;
char nameCard[1000];
public:
Playercard()
{
}
void load(char* name, bool male, int age, double cash, char* prod)
{
if(male)
{
genderStr = "Gender: Male\n";
}
else
{
genderStr = "Gender: Female\n";
}
nameStr = "Name: " + static_cast<std::ostringstream*>( &(std::ostringstream() << name))->str() + "\n";
ageStr = "Age: " + static_cast<std::ostringstream*>( &(std::ostringstream() << age))->str() + "\n";
cashHeldStr = "Cash Held: " + static_cast<std::ostringstream*>( &(std::ostringstream() << cash))->str() + "\n";
prodWantedStr = "Product Wanted: " + static_cast<std::ostringstream*>( &(std::ostringstream() << prod))->str() + "\n";
char * nameChar = new char [nameStr.length()+1];
char * genderChar = new char [genderStr.length()+1];
char * ageChar = new char [ageStr.length()+1];
char * cashHeldChar = new char [cashHeldStr.length()+1];
char * productWantedChar = new char [prodWantedStr.length()+1];
strcpy(nameChar, nameStr.c_str());
strcpy(genderChar, genderStr.c_str());
strcpy(ageChar, ageStr.c_str());
strcpy(cashHeldChar, cashHeldStr.c_str());
strcpy(productWantedChar, prodWantedStr.c_str());
strcat(nameCard, nameChar);
strcat(nameCard, genderChar);
strcat(nameCard, ageChar);
strcat(nameCard, cashHeldChar);
strcat(nameCard, productWantedChar);
diagFile.open("Diag.txt");
diagFile.write("Test", 100);
diagFile.close();
}
void setUp(int L, int T, int R, int B)
{
SetRect(&textbox, L,T,R,B);
}
void draw()
{
font->DrawTextA(d3dSprite, nameCard, -1, &textbox, DT_LEFT, D3DCOLOR_XRGB(255, 255, 255));
}
LPCSTR plCard()
{
return nameCard;
}
};
Any help would be greatly appreciated. Thank you.
Your main problem is that
nameCardis uninitialized.strcatrequires a null-terminated string to do its magic, and there’s no guarantee that the first, or any, character innameCardis a null.However, C strings are unnecessary. Just use
std::stringall the time. After changingnameCardto a string, I’d changeloadto (file writing excluded):I would actually just make
nameCarda data member, removing the others, and use this:Other than that, make
plCard()return astd::stringand indraw(), usenameCard.c_str(). I hope that clears up what you can do with strings a bit more.Do note, however, that
std::to_stringis C++11. C++03 has two common solutions:Or
I find the three-liner much more readable than a one-liner or two-liner.