throw exception after allocating some memory [modified]
-
How to let the code be more elegant? Just too much
delete
. BTW, while not to deal the exception in side the function,try catch finally
can't be used.void f()
{
char * buf = new char[128];
...
if (...)
{
delete []buf;
throw runtime_error("...");
}
...
if (...)
{
delete []buf;
throw runtime_error("...");
}
}===================== I think what I need is something like constructor and destructor, but for a function. By overriding operator() of a class may solve some problem, but the function it hard to be re-entrantable, and other misc problems. Most of the cases the function should be short, so this couldn't be a problem, but in some rare case, it has to deal a lot of data, and the function looks very long.
modified on Friday, December 24, 2010 3:38 AM
The
try-catch
block is the most elegant solution, why cannot you use it? Alternatives are theC
-likegoto
and theif
chain you depicted. :)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] -
The
try-catch
block is the most elegant solution, why cannot you use it? Alternatives are theC
-likegoto
and theif
chain you depicted. :)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] -
How to let the code be more elegant? Just too much
delete
. BTW, while not to deal the exception in side the function,try catch finally
can't be used.void f()
{
char * buf = new char[128];
...
if (...)
{
delete []buf;
throw runtime_error("...");
}
...
if (...)
{
delete []buf;
throw runtime_error("...");
}
}===================== I think what I need is something like constructor and destructor, but for a function. By overriding operator() of a class may solve some problem, but the function it hard to be re-entrantable, and other misc problems. Most of the cases the function should be short, so this couldn't be a problem, but in some rare case, it has to deal a lot of data, and the function looks very long.
modified on Friday, December 24, 2010 3:38 AM
How about this?
struct Exception
{
char *text;
void *data;
}enum ERROR{NONE,...};
void f()
{
char * buf = new char[128];ERROR e = NONE; ... if (...) e = ... if (...) e = ... if (...) e = ... if(NONE != e) { Exception exp; exp.text = FindTextForError(e); exp.data = buf; throw exp; }
}
caller()
{
try
{
f()
}
catch(Exception exp)
{
delete exp.data;
}
}...byte till it megahertz... my donation to web rubbish
-
How to let the code be more elegant? Just too much
delete
. BTW, while not to deal the exception in side the function,try catch finally
can't be used.void f()
{
char * buf = new char[128];
...
if (...)
{
delete []buf;
throw runtime_error("...");
}
...
if (...)
{
delete []buf;
throw runtime_error("...");
}
}===================== I think what I need is something like constructor and destructor, but for a function. By overriding operator() of a class may solve some problem, but the function it hard to be re-entrantable, and other misc problems. Most of the cases the function should be short, so this couldn't be a problem, but in some rare case, it has to deal a lot of data, and the function looks very long.
modified on Friday, December 24, 2010 3:38 AM
-
I think exception is rarely happened, I want to catch it in the more outside fucntion, like
main
.If you want to catch it in the main block, then why don't you just throw it? :)
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] -
How to let the code be more elegant? Just too much
delete
. BTW, while not to deal the exception in side the function,try catch finally
can't be used.void f()
{
char * buf = new char[128];
...
if (...)
{
delete []buf;
throw runtime_error("...");
}
...
if (...)
{
delete []buf;
throw runtime_error("...");
}
}===================== I think what I need is something like constructor and destructor, but for a function. By overriding operator() of a class may solve some problem, but the function it hard to be re-entrantable, and other misc problems. Most of the cases the function should be short, so this couldn't be a problem, but in some rare case, it has to deal a lot of data, and the function looks very long.
modified on Friday, December 24, 2010 3:38 AM
If you don't want to use delete all over the place, don't manually manage memory. While it's a bit hard to see the context from the pared down code you've posted why not use an automatic array of
char
or usestd::vector<char>
? Then you won't have to worry about clearing up dynamically allocated memory as you won't be using any. Cheers, Ash -
If you don't want to use delete all over the place, don't manually manage memory. While it's a bit hard to see the context from the pared down code you've posted why not use an automatic array of
char
or usestd::vector<char>
? Then you won't have to worry about clearing up dynamically allocated memory as you won't be using any. Cheers, Ash -
Yes, it is fine. But when I manapulate a dababase instead of memory, for example, a prepared statement, I need to close it before leave. Hope it can be common.
Just define your statement as a class, that will perform all needed clearances and closing in its destructor. Then - declare an instance (not an allocation by new) of the class object in the throwing function - the destructor will be called in any case (for all on-stack-instances) :)
They sought it with thimbles, they sought it with care; They pursued it with forks and hope; They threatened its life with a railway-share; They charmed it with smiles and soap. :)
-
Just define your statement as a class, that will perform all needed clearances and closing in its destructor. Then - declare an instance (not an allocation by new) of the class object in the throwing function - the destructor will be called in any case (for all on-stack-instances) :)
They sought it with thimbles, they sought it with care; They pursued it with forks and hope; They threatened its life with a railway-share; They charmed it with smiles and soap. :)
A class is ok in the case. But in another case, the life scope of the object of the class may larger than the
try..catch...
block, this can bring problems, just because the scopes are not inconsistent. However, there seems no proper way which is also efficient. BTW, is there any language that can provide some thing like constructor and distructor for a function? -
A class is ok in the case. But in another case, the life scope of the object of the class may larger than the
try..catch...
block, this can bring problems, just because the scopes are not inconsistent. However, there seems no proper way which is also efficient. BTW, is there any language that can provide some thing like constructor and distructor for a function?All of the variables local defined in a function, will be constructed on the stack at the beginning of the function and then destructed - at the end of the function (even there was a throwing) :) So you could provide a class for a function service, for example:
class CDBStatement;
class CDBStatementService // a pseudo-function-service :)
{
bool m_bOwner;
CDBStatement* m_pcStatement;public:
CDBStatementService(CDBStatement* pcStatement, bool bOwner)
: m_pcStatement(pcStatement), m_bOwner(bOwner) {};~CDBStatementService() {
if (m_pcStatement) {
m_pcStatement->Close();
if (m_bOwner) {
delete m_pcStatement;
}
}
}
};void TestThrowing()
{
CDBStatementService cDBStatementService(new CDBStatement(), true);// here could be a throwing... :)
//..} // the destructor of the service will be called, even there was a throwing
They sought it with thimbles, they sought it with care; They pursued it with forks and hope; They threatened its life with a railway-share; They charmed it with smiles and soap. :)
-
Yes, it is fine. But when I manapulate a dababase instead of memory, for example, a prepared statement, I need to close it before leave. Hope it can be common.
you said u need to close the database before u leave right ? so leave means , when the scope of that object goes away right ? so it must be possible to implement via const/dest . say for example when ur function first called the const of the object(declared inside the function) executes and when ur function terminates , the dest of the object executes. u can safely put things there right ?
If u can Dream... U can do it