I would like to do something like
FileIn::FileIn(const char* filename)
{
handle=CreateFile(filename,GENERIC_READ,FILE_SHARE_READ
,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(handle==INVALID_HANDLE_VALUE)
{
// Base class ExceptionWinapi will call GetLastError();
throw ExceptionWinapiFile(filename);
}
}
However, if the ExceptionWinapi does not copy filename, it will probably be invalid when it is time to catch the exception. But copy the filename would require a malloc (if the buffer is not fixed-length) which may fail. So where to store the string?
EDIT: To make it more clear, consider
#include <cstdio>
class Foo
{
public:
Foo(const Foo& foo){printf("Foo copy\n");}
Foo(){printf("Foo\n");}
~Foo(){printf("~Foo\n");}
};
class TestExcep
{
public:
TestExcep(const Foo& bar):m_bar(bar){}
private:
Foo m_bar;
};
class Test
{
public:
Test(const Foo& bar)
{throw TestExcep(bar);}
};
int main()
{
try
{
Foo bar;
Test a(bar);
}
catch(const TestExcep& excep)
{
printf("Error\n");
return 1;
}
return 0;
}
prints (comment added)
Foo
Foo copy
~Foo <======Destroy old Foo after copy to the exception object!
Error
~Foo
EDIT 2: if Foo(const Foo& foo){printf("Foo copy\n");} throws, then it is that exception that is cauch not the old one. This is also bad.
EDIT 3:
Useful parts of ExceptionWinapiFile
ExceptionWinapiFile(const char* filename)
{
m_length=streln(filename)+1;
m_buffer=(char*)malloc(m_length*sizeof(char));
if(m_buffer==NULL)
{
//The problem
abort(); //????
}
memcpy(m_buffer,filename,m_length*sizeof(char));
}
Also (the same problem again)
ExceptionWinapiFile(const ExceptionWinapiFile& e)
{
m_length=e.m_length;
m_buffer=(char*)malloc(m_length*sizeof(char));
if(m_buffer==NULL)
{
//The problem
abort(); //????
}
memcpy(m_buffer,e.filename,m_length*sizeof(char));
}
No problem in dtor, at least:
~ExceptionWinapiFile()
{
free(m_buffer);
m_buffer=NULL; //As recommended by boost
}