|
Yes, you ought to free the brush. Now, GDI might re-use the same brush for all solid white brushes (in which case you'll only ever create one brush), but you're probably better off creating the brush in your OnInitDialog method, assigning it to a data member and returning that from this method. You can delete that brsh in an OnClose handler or something like that.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
Stuart,
Thanks for the response. However this code is not part of a class derived from CDialog therefore, I do have a call to OnInitDialog. The base class is CFrameWnd and I was going to create the Brush when the window is first created. That is, I was going to do it in OnCreate(). Do you see any problems with that?
Now in terms of deleting the brush, can I do that by simply using the C++ operator delete? It seems to me that there should be a MFC method to delete a brush, but I can not seem to find it. I am hoping that you will tell me what it is?
Thanks
Bob
|
|
|
|
|
BobInNJ wrote: That is, I was going to do it in OnCreate(). Do you see any problems with that?
Should be fine
BobInNJ wrote: Now in terms of deleting the brush, can I do that by simply using the C++ operator delete? It seems to me that there should be a MFC method to delete a brush, but I can not seem to find it. I am hoping that you will tell me what it is?
The CBrush destructor (well, actually, the destructor of its base class, CGDIObject) deletes the GDI object. All you need to do is make sure the CBrush is destructed properly.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
Stuart,
First, I believe that you have solved my problem (my testing is still incomplete as I write this) and I thank you for it. However, I am still confused about deleting the Brush. I believe you saying that if I created the brush by using the statement:
backGroundBrush = CreateSolidBrush(RGB(255, 255, 255));
where backGroundBrush is an data member of my class CMainWindow. Now, if I have an instance of CMainWindow and delete is called on the instance of CMainWindow, then the corresponding constructor for backGroundBrush will be called which will result in the brush being cleaned up. Therefore everything will work. Do I have this right?
Thanks
Bob
|
|
|
|
|
Yes, that's correct. It uses a well-known C++ idiom called 'Resource Acquisition is Initialisation', or RAII[^].
Basically, this translates to "If you can tie the lifetime of some resource (like a BRUSH) ot a C++ object, you can allocate the resources in the constructor[^] and deallocate it in the destructor".
Unfortunately, the MFC documentation for MFC GDI object wrappers doesn't explicitly say "the GDI object is deleted in the CGDIObject destructor" - the closest it comes is in the description of using a GDI object allocated on the stack - "Allow the frame-allocated graphic object to be deleted automatically when the scope is exited"[^]. This advice holds just as true for a GDI object that is a data member of a class instance.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
Hello,
I used Visual Studio's tools for reporting memory leaks.
Main program uses a dll. In main program it reports the file name and line number:
d:\tmp\ali\ali\ali.cpp(47) : {200} client block at 0x003A84C0, subtype 0, 5000 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
but in dll it doesn't:
{199} normal block at 0x003AC018, 10000 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
This style reporting isn't usefull for me.
What's wrong here. How can i fix this problem.
thanks!!
Exe Source Code:
#include "stdafx.h"
#ifdef _DEBUG
#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__)
#else
#define DEBUG_CLIENTBLOCK
#endif // _DEBUG
#if defined(_DEBUG) && defined(WIN32)
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#endif
#include <windows.h>
#include <conio.h>
#ifdef _DEBUG
#define new DEBUG_CLIENTBLOCK
#endif
int _tmain(int argc, _TCHAR* argv[])
{
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
HINSTANCE m_kutuphane = LoadLibrary(L"DebugDLL.dll");
typedef __declspec(dllimport) void __stdcall MyDllFunction();
char getDllFunctionName[]="?dllFunction@@YAXXZ";
MyDllFunction* mf = NULL;
mf = (MyDllFunction *) GetProcAddress(m_kutuphane,getDllFunctionName);
mf();
new char[5000];
while (!_kbhit());
return 0;
}
</conio.h></windows.h></crtdbg.h></stdlib.h>
Dll Source Code:
#if defined(_DEBUG) && defined(WIN32)
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#endif
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
return TRUE;
new char[10000];
}
__declspec( dllexport ) void dllFunction()
{
std::cout << "dll: Hello!" << std::endl;
new char[10000];
}</crtdbg.h></stdlib.h>
Output :
'ali.exe': Loaded 'D:\tmp\ali\debug\ali.exe', Symbols loaded.
'ali.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll', No symbols loaded.
'ali.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll', No symbols loaded.
'ali.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC80.DebugCRT_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_5490cd9f\msvcr80d.dll', Symbols loaded.
'ali.exe': Loaded 'C:\WINDOWS\system32\msvcrt.dll', No symbols loaded.
'ali.exe': Loaded 'D:\tmp\ali\debug\DebugDLL.dll', Symbols loaded.
'ali.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC80.DebugCRT_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_5490cd9f\msvcp80d.dll', Symbols loaded.
Detected memory leaks!
Dumping objects ->
d:\tmp\ali\ali\ali.cpp(47) : {200} client block at 0x003A84C0, subtype 0, 5000 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
{199} normal block at 0x003AC018, 10000 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.
The program '[5988] ali.exe: Native' has exited with code 0 (0x0).
Compiler settings:
Exe:
/Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Gm /EHsc /RTC1 /MDd /Yu"stdafx.h" /Fp"Debug\ali.pch" /Fo"Debug\\" /Fd"Debug\vc80.pdb" /W3 /nologo /c /Wp64 /ZI /TP /errorReport:prompt
Dll:
/Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_USRDLL" /D "DEBUGDLL_EXPORTS" /D "_UNICODE" /D "UNICODE" /D "_WINDLL" /Gm /EHsc /RTC1 /MDd /Yu"stdafx.h" /Fp"Debug\DebugDLL.pch" /Fo"Debug\\" /Fd"Debug\vc80.pdb" /W3 /nologo /c /Wp64 /ZI /TP /errorReport:prompt
Linker settings:
Exe:
/OUT:"D:\tmp\ali\Debug\ali.exe" /INCREMENTAL /NOLOGO /MANIFEST /MANIFESTFILE:"Debug\ali.exe.intermediate.manifest" /DEBUG /PDB:"d:\tmp\ali\debug\ali.pdb" /SUBSYSTEM:CONSOLE /MACHINE:X86 /ERRORREPORT:PROMPT kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
Dll:
/OUT:"D:\tmp\ali\Debug\DebugDLL.dll" /INCREMENTAL /NOLOGO /DLL /MANIFEST /MANIFESTFILE:"Debug\DebugDLL.dll.intermediate.manifest" /DEBUG /PDB:"d:\tmp\ali\debug\DebugDLL.pdb" /SUBSYSTEM:WINDOWS /MACHINE:X86 /ERRORREPORT:PROMPT kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
|
|
|
|
|
The implication is that the leak with no source information originates in a file with no debug information.
However, you can get the debug heap implementation to break when that allocation is made. There is a global variable in the C run-time called '_crtBreakAlloc' that you set to the allocation number (that's the one in braces - 199 in the case where there's no source information).
See this page[^] for more details.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
I added below line to dll's code
#define new DEBUG_CLIENTBLOCK
and its working now.
|
|
|
|
|
I have managed to display a bitmap inserted in the resources,
I have tried to search the articles about the above mentioned and they
get a bit complicated,
what I have gathered, mfc dosen't support this, is this true
Can you recommend something none complex
Thanks Simon
|
|
|
|
|
What do you want to do? Please explain it more clearly.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Do you want to retouch a bitmap at your program?
Of one Essence is the human race
thus has Creation put the base
One Limb impacted is sufficient
For all Others to feel the Mace
(Saadi )
|
|
|
|
|
fun(){
int temp;
throw temp;
}
main(){
void fun1(){
try{
int a;
fun();
int* p=null;
p=new int[40]
}
catch(int temp){
delete[] p;
}
}
}
What will hapen?
|
|
|
|
|
JackPuppy wrote: What will hapen?
My guess is one or more derogatory replies since you posted code that does not compile.
|
|
|
|
|
fun(){
int temp;
throw temp;
}
void fun1(){
try{
int a;
fun();
int* p=null;
p=new int[40]
}
catch(int temp){
delete[] p;
}
}
main(){
fun1();
}
I write some code that supposed to make you understand, rather than make it perfect without any mistakes.
Alas, just edit a bit can make it compliable.
|
|
|
|
|
If you'll clean up the compiler errors, you should be able to answer your question.
"Old age is like a bank account. You withdraw later in life what you have deposited along the way." - Unknown
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
|
|
|
|
|
lol....
you make me largh!
Please look into this code because it's not that simple and it contain some deadly fallacies in it! And not just one, many!
My confusion is that I don't find a way out to solve it.
|
|
|
|
|
So has your question changed from "What will hapen?" to "How can I fix it?"
"Old age is like a bank account. You withdraw later in life what you have deposited along the way." - Unknown
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
|
|
|
|
|
JackPuppy wrote: it contain some deadly fallacies in it!
Possibly yes.
JackPuppy wrote: And not just one, many!
Again, possibly yes.
JackPuppy wrote: My confusion is that I don't find a way out to solve it.
No doubt about.
BTW: just kidding.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
JackPuppy wrote: I write some code that supposed to make you understand
I can't buy into that concept.
JackPuppy wrote: Alas, just edit a bit
No. Alas I am bored with you now.
|
|
|
|
|
What exactly do you find interesting, in the above code?
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
OK,let me expain:
fun(){
int temp;
throw temp;
}
void fun1(){
try{
int a;
fun();
int* p=null;
p=new int[40]
}
catch(int temp){
delete[] p;
}
}
main(){
fun1();
}
when main() call fun1(), a,p are push into stack without initialize.
fun()throw an exception so the try-catch block detect it.
and the program jump into catch{} and in the catch{} it delete[] p;
wait for a sec, p wasn't initialize yet so this is wrong;
however how can we determine whether p was initialize?
because when p was pushed into stack it contain some data and become a dangling pointer.
by convention, we will write catch{
if(p!=NULL)
delete[] p;
}
but it wasn't the case at this circumstance because p is not null at the very begining!
of cause you can write like this:
int* p=null;
fun();
p=new int[40];
so p is null before calling fun().
so It's OK now.
I find this interesting because I have to pay so much programing knowledge to explain this small mistake, the knowledge concerned are : stack, heap management, PE format, linker, loader, lib.
|
|
|
|
|
I believe the forum you want is called "Subtle Bugs"
|
|
|
|
|
thanks for advising. i didn't know it.
|
|
|
|
|
no problem, I'm sure you'll get a much better reception there
|
|
|
|
|
Apart from the fact his bug ain't subtle...
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|