|
When the object of my class (see below) have done its work my app crashes!
And the debuger says there is in operator 'delete' an expression error: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse). I have allocated memory in both my constructors and deleting it corectly... haven't I?
My class:
class CScoreData
{
// Public member functions
public:
CScoreData(char* player, int score);
CScoreData();
~CScoreData();
void FillData(char* player, int score);
char* GetPlayer(){ return m_chPlayer; }
int GetScore(){ return m_nScore; }
// Operator overloading
public:
CScoreData& operator=(CScoreData& sd);
// Member data
private:
char* m_chPlayer; // Player name
int m_nScore; // Player score
};
CScoreData::CScoreData()
{
m_chPlayer = new char[MAX_SD_BUFFER];
m_nScore = 0;
}
CScoreData::CScoreData(char* player, int score)
{
m_chPlayer = new char[MAX_SD_BUFFER];
FillData(player,score);
}
CScoreData::~CScoreData()
{
delete [] m_chPlayer;
}
void CScoreData::FillData(char* player, int score)
{
strcpy(m_chPlayer, player);
m_nScore = score;
}
CScoreData& CScoreData::operator=(CScoreData& sd)
{
if(this == &sd)
return *this;
strcpy(m_chPlayer, sd.GetPlayer());
m_nScore = sd.GetScore();
return *this;
}
int main()
{
CScoreData sd;
sd.FillData("Testar att vara cool",120000);
ofstream fout("file.osh",ios::binary);
if(!fout)
return 1;
fout.write((char*)&sd, sizeof(sd));
fout.close();
/////////////////////////////////////////////
/////////////////////////////////////////////
CScoreData sd2;
ifstream fin("file.osh", ios::binary);
if(!fin)
return 1;
fin.read((char*)&sd2, sizeof(sd2));
fin.close();
cout << sd2.GetPlayer() << "\n" << sd2.GetScore() << endl;
return 0;
}
------------------------------------
Rickard Andersson, Suza Computing
ICQ#: 50302279
I'm from the winter country SWEDEN!
------------------------------------
|
|
|
|
|
I believe the problem is because of the way that you are reading and writing your data out to the file. You are doing this:
Rickard Andersson wrote:
fout.write((char*)&sd, sizeof(sd));
Which will not write out the data to the character array like you expect, but the pointer that you have allocated. Then when you read in SD2 with this:
Rickard Andersson wrote:
fin.read((char*)&sd2, sizeof(sd2));
The pointer is still actually valid because sd was not yet destroyed. So when you access the data it succeeds for sd2.
Finally, when the objects delete themselves because they go off of the stack, the first object to be deleted will succeed because the pointer is valid, the second deletion will fail.
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
|
|
|
|
So, a new allocation won't cause when creating more then one object of the same class?
Okay, then I have to put those into separeted functions and read in one and write in another...
------------------------------------
Rickard Andersson, Suza Computing
ICQ#: 50302279
I'm from the winter country SWEDEN!
------------------------------------
|
|
|
|
|
Rickard Andersson wrote:
So, a new allocation won't cause when creating more then one object of the same class?
No. I will explain it again, with a little more detail.
In your code you have some thing like this:
CScoreData sd;
...
CScoreData sd2;
...
Memory is allocated for each of these objects like you would expect. The constructor is called as well, and memory is allocated by new in your constructors.
CScoreData::CScoreData()
{
m_chPlayer = new char[MAX_SD_BUFFER];
m_nScore = 0;
}
CScoreData::CScoreData(char* player, int score)
{
m_chPlayer = new char[MAX_SD_BUFFER];
FillData(player,score);
}
So after you create both of these objects, the data inside them will look something like this:
ADDRESS1 -----> Points to a buffer [hello]
ADDRESS2 -----> Points to a different buffer [goodbye]
THIS IS NOT CODE, I AM ATTEMPTING TO DISPLAY WHAT DATA IS CONTAINED IN YOUR OBJECTS
sd
{
m_chPlayer = [ADDRESS1]
m_score = 0
}
sd2
{
m_chPlayer = [ADDRESS2]
m_score = 0
}
Then you write the sd object to the file. What will actually be written with the code that you are using is something like this:
[object info][ADDRESS1]0
Then when you read the data into object sd2, all of sd2 data is overwritten by the data in the file (this is the nature of the way you are using read), and the data in sd2 will look like this:
sd2
{
m_chPlayer = [ADDRESS1]
m_score = 0
}
Notice that it is using the same memory address as sd1. Therefore when you attempt to use the data in sd2, it appears to work, but you are referring to the same address that sd uses. Then when you go to delete the two objects, they both attempt to delete the buffer at ADDRESS1, and that is where your memory problem is occurring.
In order to fix this, I would recommend to not allocate the memory in your object, but create a static array, and then the code will work the way that you have written it. So change your class definition to this:
class CScoreData
{
...
private:
char m_chPlayer[MAX_SD_BUFFER];
int m_nScore;
};
Or you can overload the stream operators for your class to serialize the object operator<< and operator>> .
Then instead of using fout.write to write the data to the file you would use fout << sd; to write your data to the file.
Or write each of the fields from the class to the file separately, because with dynamic memory allocation, you cannot correctly write the data to a file the way that you are trying.
Good luck
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
|
|
|
|
I was so sure I had tried that and it crashed too, but I tried again writing
kilowatt wrote:
char m_chPlayer[MAX_SD_BUFFER]; // Player name
and now it working! Big thank to ya!
------------------------------------
Rickard Andersson, Suza Computing
ICQ#: 50302279
I'm from the winter country SWEDEN!
------------------------------------
|
|
|
|
|
Imagine:
You have 2 workstations A and B and a couple of users UNr1, UNr2, ....
Is it possible to connect more than one user via workstation A to workstation B , meaning different Users use the same workstation (A) to connect to a other workstaion (B) ???
I have tried it with services but i failed because i don't know how to create a service at RUNTIME!!!
|
|
|
|
|
|
Is it possible to create ActivX control in vC++ cause i dont have the option on the new project wizard.
|
|
|
|
|
Normally it is possible, and there should be an option on the new project wizard named "MFC ActiveX ControlWizard", but if you see none, I don't know how to help
|
|
|
|
|
Yes, it is possible to create ActiveX controls using Visual C++. But it is not as easy as that of VB. The prerequisite is to have some background information about COM and Automation. Few examples of ActiveX controls created in VC++ can be found here
Imran Farooqui
|
|
|
|
|
The activeX control i wanna create is for the web so really it needs to be done in c++ cause if it was done in vb then a user without msvbvm60.dll wont be able to use it P
|
|
|
|
|
My problem rises as I'm making a "View" menu which allows the user to toggle control bars' visibilities. I can't make my menu valid when the user close a control bar by clicking the x button on the top right corner of the control bar window.
|
|
|
|
|
In your update handler for the menu item, use the IsVisible() method of the control bar to determine whether or not to check the menu item.
--------
I'm not sick, but i'm not well
And i'm so hot, 'cause i'm in hell... Harvey Danger, Flagpole Sitta
|
|
|
|
|
I've tried that, but the IsVisible() method doesn't seem to work properly in CControlBar class. Maybe I've made mistakes, I'll try again. Thanks anyway
|
|
|
|
|
Hi,
i'm trying to display a bitmap resource in a dialog box but haven't had much success.
Anyone can help?
Malf
|
|
|
|
|
This is the way I do to insert an image in a dialog box.
1. Add a bitmap resource (IDB) to use to the project.
2. Add a picture control to the dialog.
3. Set the type of the newly-added control to Bitmap.
4. Map a CStatic variable (m_A) to the control.
5. Add a CBitmap variable (m_B) to the dialog class.
6. In the dialog's "OnInitialUpdate()" function, type:
m_B.LoadBitmap(IDB); // VERIFY macro can be used.
m_A.SetBitmap(m_B);
|
|
|
|
|
What is wrong with that damned function! CreateProcessWithLogonW() doesn't want to work right! The first 3 parameters could be absolutly every sh*t, and the function doesn't get excited!!! It makes no difference if you write:
CreateProcessWithLogonW("testuser@domain.com","","",....) or
CreateProcessWithLogonW("testuser","domain.com","",....) or
CreateProcessWithLogonW("testuser@domain.com","\\\\machine","",...) or
CreateProcessWithLogonW("f***off","","",....) or
CreateProcessWithLogonW("f***off","\\\\my brain hearts","nice weather",....)
It allways returns true!!!!!! What must i do to get it work RIGHT ???
|
|
|
|
|
ummmm u r on win2k right?
situations to avoid #37: "good morning ... how many sugars do you take in your coffee ... and what was your name again?"
|
|
|
|
|
|
I just tried it and it works/fails when it should. I couldn't test the domain bit because all my PCs are defined in a worksgroup - looks like they ignore that parameter in that case. However, if I type the wrong userid or password, the function fails and it succeeds if the user info is correct.
Cheers,
Tom Archer
Author, Inside C#
Please note that the opinions expressed in this correspondence do not necessarily reflect the views of the author.
|
|
|
|
|
Dunno what wrong you are doing. I made a small test and got the function working *shrugs* Here is the code:
STARTUPINFOW su_info;
ZeroMemory(&su_info, sizeof(STARTUPINFOW));
su_info.cb = sizeof(STARTUPINFOW);
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
CreateProcessWithLogonW(L"user", L"computer-name", L"password", 0,
L"D:\\Winnt\\notepad.exe" , NULL, 0, NULL, NULL, &su_info, &pi);
Of course I changed the Username, password and computer name before posting it
Philip Patrick
Web-site: www.stpworks.com
"Two beer or not two beer?" Shakesbeer
Need Web-based database administrator? You already have it!
|
|
|
|
|
yeah, but did you try different parameters for user, domain, and password and are you shure that the process than runs under the RIGHT security context ??
|
|
|
|
|
hph wrote:
did you try different parameters for user, domain, and password
Tried different user, not domain. I have only one computer at home
hph wrote:
are you sure that the process than runs under the RIGHT security context
Check it, if you know how. Or ask Microsoft to send you the source code
I believe that if the function suppose to run a process under right context, it will.
Philip Patrick
Web-site: www.stpworks.com
"Two beer or not two beer?" Shakesbeer
Need Web-based database administrator? You already have it!
|
|
|
|
|
Could it be possible that CreateProcessWithLogonW() only works for Local users? I tried it many times and it works only if the user is a local one!
It seems that a domain, can't be a other workstation(of course)!!
... you can check the security context, if you try to access files! At the error code you can see whether you have the needed rights or not!!
|
|
|
|
|
You are right, look:
From MSDN:
The user account must have Log On Locally permission on the local computer. This permission is granted to all users on workstations and servers, but only to administrators on domain controllers.
Philip Patrick
Web-site: www.stpworks.com
"Two beer or not two beer?" Shakesbeer
Need Web-based database administrator? You already have it!
|
|
|
|
|