|
|
I am somewhat familiar with a try-catch block and that it automatically destructs objects on exception. However, I'm curious if it automatically frees dynamically allocated memory from the "new" operator?
void failfunc()
{
throw 1;
}
void main()
{
try
{
char *mystr = new char[512];
failfunc();
delete [] mystr;
}
catch (int ierr)
{
if (mystr != NULL) delete [] mystr;
}
}
|
|
|
|
|
You have allocated memory in a heap by using new.
And after that you are executing the next statement which is failing.
As i Know you should delete the memory which is created dynamically.
So in catch statement the deletion part is must.
But if
failfunc();
char *mystr = new char[512];
be allocated in the try block
Statement 1.....
delete [] mystr;
then as function failed it will not try to execute the next statment so there it will skip the creation of memory .so you need not to delete ....
|
|
|
|
|
No, you have to free the memory yourself.
|
|
|
|
|
Objects allocated on the heap (i.e. via new ) are not freed automatically. Objects allocated on the stack (like MyObject obj; ) are freed when they go out of scope (i.e. when the execution leaves the innermost {} that surrounds the declaration) or when an exception is thrown. So in your example, if failfunc() throws an exception other than an integer (which can easily happen when someone changes failfunc() but not main()), you got yourself a memory leak.
However, you can use what's called a smart pointer to get the desired behavior. The smart pointer is is a helper class that is allocated on the stack and behaves like a regular pointer, and when an exception is thrown its destructor gets called. In that destructor, it calls delete[] on its pointee. Just google smart pointers.
Example (not tested):
template< typename T >
class ArrayPtr
{
public:
ArrayPtr( T* pointee )
: _pointee( pointee )
{
}
inline ~ArrayPtr() {
if( _pointee )
delete[] _pointee;
}
operator T*() {
return _pointee
}
private:
T* _pointee;
};
void failfunc()
{
throw 1;
}
void main()
{
try {
ArrayPtr< char > mystr( new char[512] );
failfunc();
} catch( int err ) {
std::cerr << "Error #" << err << std::endl;
}
}
Or if you don't need to print out an error message:
template< typename T > class ArrayPtr { };
void failfunc() { }
void main()
{
ArrayPtr< char > mystr( new char[512] );
failfunc();
}
Note that you cannot use the standard C++ std::auto_ptr for arrays since its destructor only calls delete , not delete[] . This also implies that you need a separate smart pointer type for data allocated with malloc since it must be freed using free , not delete[] .
I suggest that you use smart pointers, otherwise you'll end up having loads of manual try...catch blocks just for ensuring that memory is freed properly, which is hard to maintain and leads to bugs. Also note that the version of main() using the smart pointer is much shorter than your original one since you don't need all the cleanup code.
If sombody now changed failfunc() to throw something else than an integer, your memory would still be freed correctly since the smart pointer would take care of that.
Hope that helps
Peter
|
|
|
|
|
Thanks very much for the descriptive information. The example code is an excellent solution for my problem. I really appreciate you taking the time to answer that thoroughly.
|
|
|
|
|
Glad I could help
|
|
|
|
|
You could use something like Boost[^]'s scoped_array[^] to avoid having to free the memory using a catch .
Steve
|
|
|
|
|
Hai !
Good Morning !
I have created a MSI installer , when i press setup.exe it copies MyApp1.exe , MyApp2.exe in the destination folder , but the problem is that i have MyApp.exe in customs action of setup project, which must be executed once the exe files are copied to the destination folder
thanks
kapardhi
|
|
|
|
|
This is not the right forum to get the question answered.
Somethings seem HARD to do, until we know how to do them.
_AnShUmAn_
|
|
|
|
|
"Costum action" screams for running your app with "/install". Write the install co dein your app.
Greetings from Germany
|
|
|
|
|
We are building our system which has hundred's of workspaces for which debug info is not set manually so now for debugging release binaries we are building through batch file which has following script
Set ReBuild_Required=
if /I "%1"=="clean" GOTO CLEAN
if /I "%1"=="clean_only" GOTO CLEAN_ONLY
Set Config=%1
if /I "%Config%"=="" Set Config=Release
GOTO BUILD
:CLEAN_ONLY
Set ReBuild_Required=/CLEAN
GOTO CLEAN_REMAINING
:CLEAN
Set ReBuild_Required=/REBUILD
:CLEAN_REMAINING
Set Config=%2
if /I "%Config%"=="" Set Config=Release
del /Q ..\..\Include\*.*
del /Q ..\..\..\Common\Include\*.*
if /I %Config%==Release GOTO CLEAN_RELEASE
del /Q ..\..\Bin\Debug\*.*
del /Q ..\..\..\Common\Bin\Debug\*.*
del /Q ..\..\Lib\*Dbg.Lib
del /Q ..\..\..\Common\Lib\*Dbg.Lib
GOTO BUILD
:CLEAN_RELEASE
del /Q ..\..\Bin\Release\*.*
del /Q ..\..\..\Common\Bin\Release\*.*
ren ..\..\Lib\*Dbg.Lib *Dbg.Tlf
del /Q ..\..\Lib\*.Lib
ren ..\..\Lib\*.Tlf *.Lib
ren ..\..\..\Common\Lib\*Dbg.Lib *Dbg.Tlf
del /Q ..\..\..\Common\Lib\*.Lib
ren ..\..\..\Common\Lib\*.Tlf *.Lib
:BUILD
Set Proj_Dir=..\..\..\Common\Source\Database
Set Proj_Name=DBRecall
MSDEV /USEENV %Proj_Dir%\%Proj_Name%\%Proj_Name%.dsp /MAKE "%Proj_Name% - Win32 %Config%" %ReBuild_Required%
if %ERRORLEVEL% GEQ 1 GOTO end
In the above script what changes I need to do inorder to generate debug info??
|
|
|
|
|
|
Hello dear friends,
Is there any API for changing the "Language support for non-Unicode language"? This is required because I've to add Russian language support in my application.I've created a string table in which I copy/paste the russian strings from excel.The problem is all characters become ???.
When I go to Control Panel->Regional and Language options->Advance tab and changing the language to Russian solves the problem and all the strings of russian displayed without any problem but this changes require to reboot the PC.I want to set this options from the API's so is there any API for this thing or any other way to do this?
Thanks in advance.
ritz1234
|
|
|
|
|
how can create data base in vc++6 (programatically)
CDBAccess *pdba;
pdba = new CDBAccess;
pdba->m_sFilePath = "";
pdba->NewDBFile();
this code is not working
error is
error C2039: 'NewDBFile' : is not a member of 'CDBAccess'
|
|
|
|
|
ani_ikram wrote: : 'NewDBFile' : is not a member of 'CDBAccess'
Is NewDBFile defined in CDBAccess?
Somethings seem HARD to do, until we know how to do them.
_AnShUmAn_
|
|
|
|
|
NewDBFile is not member of CDBAccess
but i want to create database using vc++6
how can create
|
|
|
|
|
Then how come you try to access that member function. You would need to write your own version of NewDBAccess
Somethings seem HARD to do, until we know how to do them.
_AnShUmAn_
|
|
|
|
|
Hi all
I am trying to debug a service and this happens, my output are Connector.exe <-the service, ConnectorTray.exe <- the gui and ConnectorCpl. There are 3 different projects for this. What does this mean? What should I do?
An exception occurred while trying to run "Shell32.dll,Control_RunDLL ConnectorCpl.cpl"
Thanks,
Jayjay
|
|
|
|
|
i have i library UBA.lib in my project. i have set project settings (link) as
c:\dxsdk\lib\ddraw.lib c:\dxsdk\lib\dxguid.lib vfw32.lib winmm.lib "C:\Nova_Svep2\Common Classes\UBA.lib"
still this error ,what can be reason and how can solve this error
LINK : fatal error LNK1104: cannot open file "C:\Nova_Svep2\Common Classes\UBA.lib"
|
|
|
|
|
Add only UBA.lib and add Directory path to Tool->Options->Directroies->Library Files
May be this zcan help you.
-@SuDhIrKuMaR@-
|
|
|
|
|
Hi,
In my application I can dynamically create a menu at the top of my window and also dynamically remove it. After I created it, calling "GetClientRect" returns the correct client area (previous area-area occupied by the menu bar). Now when I remove the menu bar, the client area is not updated. Only if I resize the window or move the window will the value returned by "GetClientRect" be updated correctly. How come? Is there a workaround?
BTW I remove my menu bar with following code:
[source]
CMenu* it=GetMenu();
if (it!=NULL)
{
int nb=it->GetMenuItemCount();
for (int i=0;i<nb;i++)>
it->RemoveMenu(0,MF_BYPOSITION);
DestroyMenu(it->m_hMenu);
}
[/source]
Or is there a windows function I can call to force a similar behaviour like when resizing the window?
Thanks
|
|
|
|
|
Hi everyone,
I have a question that may sound a bit strange: What's the most efficient and elegant way to define constants in C++?
I'm in a situation where I have to define constants that might be used in code that needs to be as fast as possible (such as maybe image or sound processing for example). I know the standard way in C++ is like this:
const float myConst;
const float myConst = 3.5;
Based on my understanding, the initialization must be performed in myFile.cpp since only int constants can be initialized in the header.
The problem is that this looks a lot like the constant won't be inlined but always read from memory (or processor cache of course) when it is accessed. What's worse is that client code will most likely use myFile as part of a DLL/SO, so even if there were the slightest chance that the linker were trained to perform some magic inlining when linking the binary, I'd still be out of luck. Apart from that I need a portable solution that works reliably on Windows, Linux, Mac OS X, and if possible also on SGI Irix, independent of the compiler and linker.
The obvious solution is to just use #define myConst 3.5 , but I'd like to avoid that if possible (for obvious reasons).
If I'm right about no inlining being performed, does anyone have any proven workaround for this? All I could come up with was maybe abusing inline functions roughly like so (not tested, just an idea):
#define INLINE_CONST( TYPE, NAME, VALUE ) \
struct FastConst_T_##NAME { \
inline operator TYPE { return (VALUE); } \
} NAME
which then could be used like that:
INLINE_CONST( double, pi, 3.141592653589793238462 );
inline double circleArea( radius ) {
return r * r * pi;
}
But that's obviously not a very elegant solution. I'm really sorry for the lengthy post, but I can't believe I have to use such hacks to get C++ to inline my constant values. I already tried Google, but I didn't find anything useful.
Thanks in advance,
Peter
|
|
|
|
|
If it weren't for the doubles, I'd say use enum. It is definitely inline, and it has scope.
Otherwise, you could probably use an inline function:
double MyConstFunc() { return 3.5; }
It should be inline, and you write it inside the header. I don't know how it would work with dlls though.
There is sufficient light for those who desire to see, and there is sufficient darkness for those of a contrary disposition.
Blaise Pascal
|
|
|
|
|
Thanks for your reply. Inline functions are not a problem with DLLs since the implementation has to be inside the header files, which means that the source code is available and can be inlined by the compiler, so no problem there.
The solution you are proposing is exactly what the macro from my post would do (the macro would just add the benefit that it is transparent to client code because it would provide the semantics of a regular const). But I found it hard to believe that C++ offers no built-in solution. I mean, the standard allows inlining of functions, but it doesn't seem to be able to inline constants. Well, I guess I'll just have to bite the bullet and live with it then.
Thanks again,
Peter
|
|
|
|