|
I would argue that setting the pointer variable back to NULL after deleting the object is critical and highly recommended. If you do not, you are leaving a dangling reference to something that no longer exists. Once the memory is deallocated, by delete, the memory can be used for something else by another part of the program. If someone else is checking the pointer value against NULL, then the reset of the ptr to NULL will prevent a crash. My philosophy is that if the pointer doesn't point to anything then it should be null. NEVER EVER leave a pointer set to an address that is no longer pointing to a valid object. That is just asking for trouble in my mind. Of course deleting an object in the middle of program execution is tricky to begin with. There has to be an understanding between the piece of software responsible for deleting the object and the piece(s) of software using the pointer. Setting the pointer back to NULL is a simple way of establishing that understanding. If the pointer is NULL, don't use it!
//perhaps this is done in the constructor of a class and the pointer
//mlpszFilePath is a member variable of some class.
LPTSTR mlpszFilePath = NULL;
//Now in some member function you do this:
//Only build the string if it has not already been built
if(lpszFilePath == NULL)
{
mlpszFilePath = new _TCHAR chFilePath[_MAX_PATH];
}
//later you'd do this:
//Only delete the array if it has been previously allocated; perhaps in a class destructor.
if (mlpszFilePath != NULL)
{
delete[] mlpszFilePath ;
mlpszFilePath = NULL;
}
//Perhaps you have a function to get the pointer
const LPCTSTR GetPointer() const
{
return mlpszFilePath;
}
Perhaps a string is a bad example but you might have this kind of code where you have to new and delete some object that is placed in the global scope via a pointer variable that many components of an application need access to. Notice that the setup allows the same object to be reused over and over.
This type of pattern is very common and sort of applies to your other question about performance surrounding new and delete.
Yes, new and delete require system resources like any function call or calculation; but the operating system is designed to perform memory management for you so that you don't have to worry about it.
If you are only rarely using new and delete to allocate a string it's not a big deal. If you are doing it thousands of times in a second, then that could be a problem.
If the function using the string only uses the string within the block of the function, you might as well make it static or just make the string local to that scope in your program. If the string needs to continue to exist after the function completes, you have to use 'new' otherwise the string will not exist after the function call. lets say you are passing the string to another function and then the function creating the string ends. Well if you don't use new in that case, the string goes out of scope when the function creating it ends and the function you passed the pointer to is out of luck and has a dangling reference to an object that's been deallocated.
I know nothing about your application and have no idea whether to use new or delete vs. a static character array. It all depends on what you need the string for. It's totally situational. Do not be afraid to use new and delete if you have a legitimate purpose for doing so. That is why the operations exist.
|
|
|
|
|
I want to override the behaviour of WM_NCCALCSIZE and WM_NCPAINT to properly calculate the border sizes and then handle the painting of these borders for controls in my framework. So far I have it working perfectly for cases where no scroll bar is present. However if the control has the WS_HSCROLL or WS_VSCROLL style set then there are problems. In WM_NCCALCSIZE i am accounting for the presence of the scrollbar. But when the scroll bars are visible they never show up! Sometimes when I click in the right spot I can get them to appear, but the don't get redrawn correctly. Is there some other step I am missing?
¡El diablo está en mis pantalones! ¡Mire, mire!
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
SELECT * FROM User WHERE Clue > 0
0 rows returned
|
|
|
|
|
|
While CMenu::TrackPopupMenu() is called, I wish to trap the WM_LBUTTON down and WM_LBUTTONUP messages, however CMenu doesn't have a message map. Is there a way of doing this by overriding the default menu proc? (is it called a menu proc or a window proc for a menu?) If so, how is this done?
Thanks,
Jeff
|
|
|
|
|
I tried this to create a 4-bit Bitmap, but can't draw on it once selected in to the DC:
bmp.CreateBitmap(nWidth, nHeight,1,4, NULL);
Do I need to setup a palette? If so, what are the basic steps to do that?
Thanks,
PinHead
|
|
|
|
|
Can anyone explain why DeleteColumn is not deleting all columns. If I insert say 7 columns and loop through and delete each column. It deletes only 4 columns. DeleteColumn returns false after 4. Any ideas?
Thansk
|
|
|
|
|
Are you by any chance doing
for(int i = 0; i < numColumns; ++i)
listCtrl.DeleteColumn(i); If so, think about what happens. Compare that code to
for(int i = 0; i < numColumns; ++i)
listCtrl.DeleteColumn(0);
If I assumed correctly, you will feel a big "DOH!" coming out through your mouth.
--
Ich bin Joachim von Hassel, und ich bin Pilot der Bundeswehr.
Welle: Erdball - F104-G Starfighter
|
|
|
|
|
DOH!,
It makes sense, Thanks
|
|
|
|
|
Sometimes programming just sucks, doesn't it
¡El diablo está en mis pantalones! ¡Mire, mire!
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
SELECT * FROM User WHERE Clue > 0
0 rows returned
|
|
|
|
|
This is, by far, the strangest problem I have ever encountered.
I have an application, working on top windows media encoder. The Encoder is very heavy COM object, and so I created a separate thread for it. And here is the strange part on some machine, after the encoder starts working, if you try to move the window, everything stuck. On other machine – it’s working perfectly. P4 2.8 was stuck, while this laptop, P4 2.53 was working fine. The machines all have winxp on them. In this application I have 3 threads: the main mfc one, one thread for the socket communication and one for the encoder. I am sending user messages to the dialog window (the application is dialog based), but they are all more then user message value. How cam that it’s happen only on certain machine while others works fine? Any ideas?
TY!
|
|
|
|
|
Hmmm, it the 2.8GHz hyperthreaded?
Then it runs the program a lot like a dual-cpu computer will do it. And trust me, you will find the strangest threading errors on dual-cpu computers...
If this is the case, you might have some sort of thread deadlock in yout program.
- Anders
Money talks, but all mine ever says is "Goodbye!"
ShotKeeper, my Photo Album / Organizer Application[^]
My Photos[^]
New developersite: RealDevs.Net
|
|
|
|
|
Aragorn@Gondor wrote:
The Encoder is very heavy COM object, and so I created a separate thread for it.
Has the thread joined the apartment, or is it running in its own MTA? I wish I had the COM book by the Don Box guru with me right now. I recall reading about calls across apartment boundaries may hang. Gah, how frustrating! I can't remember the scenario in which it could occur.
But anyway, perhaps you could google for don box apartment hangs rpc. I'm sorry I couldn't be of much more help.
And yeah, you may want to post this in the COM forum. I bet it's related to COM in some way.
--
Ich bin Joachim von Hassel, und ich bin Pilot der Bundeswehr.
Welle: Erdball - F104-G Starfighter
|
|
|
|
|
Here is the code:
#pragma once
class Model
{
public:
Model(void);
~Model(void);
private:
std::vector<std::pair<AcGeLineSeg2d, double> > lines;
};
I am using Visual Studio 2003.
The main problem is that I'll add #include <utility> and instantly I have 30 or more errors. Even more fascinating, if I remove #include <utility> it still gives those same messages! It would be nice if I could get it to compile "std::vector<std::pair<AcGeLineSeg2d, double> > lines;" without an error. It gives error C2143: syntax error : missing ';' before '<'.
Thanks for your consideration,
Sean
|
|
|
|
|
Did you try to #include "vector" ?
|
|
|
|
|
Yes I had tried that- I've tried a lot of things. That works for getting rid of compile errors on that particular line, but does nothing with the xutility errors...
|
|
|
|
|
Could you please post operators definitions here if you have any?
[UPDATE]
I meant your AcGeLineSeg2d of course.
|
|
|
|
|
There aren't any operators defined.
In fact, my code is as simple as it gets. What is even weirder is that the xutility errors showed up in a new project that doesn't even use pair or even any header files, aside from #include "vector" (which should really be "class vector;", but that is something altogether different).
|
|
|
|
|
Wait a second...
You're using STL right? So you have to include STL classes headers (like include "vector", cuz vector is a member of STL) and suggested forward declaration "class vector" will give you nothing but an error. What to xutility error, check your code carefully for dummy errors. All I've ever got from xutility is some warnings.
|
|
|
|
|
With very little work, I got the code to work in 6.0. For that reason, I will momentarily stop using .NET 2003 until absolutely necessary.
Thanks for your time!
Sean
|
|
|
|
|
Hi there,
I have this problem with two classes which need to access each other's methods. Allow me to exemplify:
<br />
class CBaseClass<br />
{<br />
public:<br />
CDerivedClass *pDerived;<br />
.<br />
:<br />
.<br />
};<br />
<br />
class CDerivedClass<br />
{<br />
public:<br />
CDerivedClass()<br />
{<br />
CBaseClass *pBaseClass;<br />
.<br />
:<br />
.<br />
};<br />
.<br />
:<br />
.<br />
};<br />
Now, as you may have guessed by now, I can't compile this as the compiler doesn't recognise CDerivedClass (it is declared after CBaseClass...).
I know this can be solved -- I just don't know how. Could you please give me a hand?
That would be much appreciated.
David
|
|
|
|
|
Use a declaration or move the CDerivedClass definition above CBaseClass'.
Example:
class CDerivedClass;<DIV>
class CBaseClass
{
public:
CDerivedClass* pDerived;
.
.
. This works. It's the same thing as using function declarations, e.g. header files, etc.. If you forget to write the CDerivedClass definition now, you'll get a linker error.
-Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|
Thanks Antti, once again.
I did exactly like you said (which is very logical, now that I think about it), but it isn't working yet. This time I get different compiling errors:
m:\~alibrary\projects\vc++\xig1\v2.0\xig1view.h(27) : error C2027: use of undefined type 'CXiG1View'<br />
m:\~alibrary\projects\vc++\xig1\v2.0\xig1view.h(15) : see declaration of 'CXiG1View'<br />
m:\~alibrary\projects\vc++\xig1\v2.0\xig1view.h(27) : error C2065: 'classCXiG1View' : undeclared identifier<br />
m:\~alibrary\projects\vc++\xig1\v2.0\xig1view.h(35) : error C2027: use of undefined type 'CXiG1View'<br />
m:\~alibrary\projects\vc++\xig1\v2.0\xig1view.h(15) : see declaration of 'CXiG1View'<br />
m:\~alibrary\projects\vc++\xig1\v2.0\xig1view.h(35) : error C2227: left of '->pConsole' must point to class/struct/union<br />
m:\~alibrary\projects\vc++\xig1\v2.0\xig1view.h(35) : error C2227: left of '->Output' must point to class/struct/union
By the way:
CXiGView is a CFormView (and has a CPrompt object)
CPrompt is declared before CXiG1View (and is a custom control derived class)
I declared the classes in the following way now:
class CXiG1View;
class CPrompt : public CXCommandPrompt
{
public:
CPrompt()
{
CWnd *pParent;
.
:
.
};
class CXiG1View : public CFormView
{
.
:
.
What am I missing out here?
|
|
|
|
|
There seems to be nothing wrong with the declaration you posted. Perhaps there's a typo or a syntax error (missing semicolon or something) somewhere else in your file ? I would check the lines that the compiler is suggesting, and the lines above/below them for typos/errors.
Unfortunately I can't find the error for you, you just need to go through the file with a magnifying glass.
To avoid similar problems in the future, I would suggest you (or your company, whichever) to familiarize yourselves with the excellent "Visual Assist X" tool from Whole Tomato Software. It simplifies and helps coding. And A LOT that is
For a quick link, go here.
-Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|
Thanks for all your help Antti! You have really been very helpful.
You can't imagine how tired I am; I'm having memory blocks [or loss, I don't know anymore!] due to the excessively coffee drank till now. I have been up for 21 hours now, non stop, working on this [new] project that just came up and, to complicate things even more, i've done MFC programming for only a month -- we're short on staff.
But thanks to you I have managed to finally put up all the pieces together (the custom controls I have been working on) and link/attach them to the CFormView-derived class.
Finally! Thank you very much Antti; I can finally go to bed (with some valuable lessons learned on the way -- hmm not too bad! )
David
PS: That tool you've mentioned before seems to be very interesting -- am going to give it a try tomorrow.
|
|
|
|
|
Hello,
I have been working on a project that interops between C# in .NET and unmanaged C++. Here's the jist: my main is in C++, and in it, i create an instance of an object made in C#. The C# is supposed to connect to the database, sort through the results and put the information into a bunch of arrays which are sent back to the C++ porition. While i got the two projects to connect and communicate somewhat, I am now having some issues with datatypes...or so i think.
Here's what i've got in C++:
...
double vd[100];
int vi[100];
string vs[100];
//send arrays to Read() method in C#
spConnNET->Read(vi, vd, vs);
The Read() method in C# looks like this:
...
public void Read(int[] intArray, double[] doubleArray, string[] stringArray)
{
while(reader.NextResult())
{
//THere will be other stuff here
reader.Read();
}
}//end Read()
when i try to compile in C++, this is the error i'm getting:
error C2664: 'DBConnection3::IConnection::Read' : cannot convert parameter 1 from 'int [100]' to 'SAFEARRAY *'
"SAFEARRAY"??!?! what the heck is that?? I thought it was "int, double, string"??
EDIT: I have tried looking up SAFEARRAY and whether it can be converted into an int/double/string and vice versa, but I don't fundamentally understand why this type conversion is taking place, what it means, what can be done...etc...
my apologies in advance for my newbie-ness...I would really appreciate some advice!
|
|
|
|