G00fy
asked on
static string & getcwd...
working code:
// --code--
[KString-class]
/*
KString( char* invoer, bool delete_invoer = false );
KString( wchar_t* invoer, bool delete_invoer = false );
*/
[CFile-class]
static KString FileDirectory;
[KString-implementation]
/*
KString::KString( char* invoer, bool delete_invoer )
{
wchar_t *_ptr;
long len(strlen(invoer));
_ptr = GiveStringOfLength(len);
mbstowcs( _ptr, invoer, len );
_ptr[len] = L'\0';
UpdatePointer( _ptr );
if ( delete_invoer )
delete [] invoer;
}
KString::KString( wchar_t* invoer, bool delete_invoer )
{
wchar_t *_ptr;
long len(wcslen(invoer));
_ptr = GiveStringOfLength(len);
wcsncpy( _ptr, invoer, len );
_ptr[len] = L'\0';
UpdatePointer( _ptr );
if ( delete_invoer )
delete [] invoer;
}
*/
[CFile-implementation]
KString CFile::FileDirectory( _T("") );
\\ -- code --
Non-working code:
// --code--
[KString-class]
KString( char* invoer, bool delete_invoer = false );
KString( wchar_t* invoer, bool delete_invoer = false );
[CFile-class]
static KString FileDirectory;
[KString-implementation]
KString::KString( char* invoer, bool delete_invoer )
{
wchar_t *_ptr;
long len(strlen(invoer));
_ptr = GiveStringOfLength(len);
mbstowcs( _ptr, invoer, len );
_ptr[len] = L'\0';
UpdatePointer( _ptr );
if ( delete_invoer )
delete [] invoer;
}
KString::KString( wchar_t* invoer, bool delete_invoer )
{
wchar_t *_ptr;
long len(wcslen(invoer));
_ptr = GiveStringOfLength(len);
wcsncpy( _ptr, invoer, len );
_ptr[len] = L'\0';
UpdatePointer( _ptr );
if ( delete_invoer )
delete [] invoer;
}
[CFile-implementation]
KString CFile::FileDirectory( _tgetcwd(NULL,MAX_PATH), true );
\\ -- code --
Now my question is easy:
"WHY!?!" ;)
The non-working version just crashes regsvr32.exe with an "invalid access to memory location"
// --code--
[KString-class]
/*
KString( char* invoer, bool delete_invoer = false );
KString( wchar_t* invoer, bool delete_invoer = false );
*/
[CFile-class]
static KString FileDirectory;
[KString-implementation]
/*
KString::KString( char* invoer, bool delete_invoer )
{
wchar_t *_ptr;
long len(strlen(invoer));
_ptr = GiveStringOfLength(len);
mbstowcs( _ptr, invoer, len );
_ptr[len] = L'\0';
UpdatePointer( _ptr );
if ( delete_invoer )
delete [] invoer;
}
KString::KString( wchar_t* invoer, bool delete_invoer )
{
wchar_t *_ptr;
long len(wcslen(invoer));
_ptr = GiveStringOfLength(len);
wcsncpy( _ptr, invoer, len );
_ptr[len] = L'\0';
UpdatePointer( _ptr );
if ( delete_invoer )
delete [] invoer;
}
*/
[CFile-implementation]
KString CFile::FileDirectory( _T("") );
\\ -- code --
Non-working code:
// --code--
[KString-class]
KString( char* invoer, bool delete_invoer = false );
KString( wchar_t* invoer, bool delete_invoer = false );
[CFile-class]
static KString FileDirectory;
[KString-implementation]
KString::KString( char* invoer, bool delete_invoer )
{
wchar_t *_ptr;
long len(strlen(invoer));
_ptr = GiveStringOfLength(len);
mbstowcs( _ptr, invoer, len );
_ptr[len] = L'\0';
UpdatePointer( _ptr );
if ( delete_invoer )
delete [] invoer;
}
KString::KString( wchar_t* invoer, bool delete_invoer )
{
wchar_t *_ptr;
long len(wcslen(invoer));
_ptr = GiveStringOfLength(len);
wcsncpy( _ptr, invoer, len );
_ptr[len] = L'\0';
UpdatePointer( _ptr );
if ( delete_invoer )
delete [] invoer;
}
[CFile-implementation]
KString CFile::FileDirectory( _tgetcwd(NULL,MAX_PATH), true );
\\ -- code --
Now my question is easy:
"WHY!?!" ;)
The non-working version just crashes regsvr32.exe with an "invalid access to memory location"
ASKER
1. Because the ATL-COM Dll registers itself by using regsvr32.exe ... And then I get this error. So I'm debugging now with the regsvr32.exe-executable...
2. CFile is my class, not MFC. The difference are the comments (watch the KString(char*,bool) and KString(wchar_t*,bool) constructors be (un)commented. Another difference is the CFile::FileDirectory statement being initialised differently.
2. CFile is my class, not MFC. The difference are the comments (watch the KString(char*,bool) and KString(wchar_t*,bool) constructors be (un)commented. Another difference is the CFile::FileDirectory statement being initialised differently.
The only difference I see is
KString CFile::FileDirectory( _tgetcwd(NULL,MAX_PATH), true ); // bad
KString CFile::FileDirectory( _T("") ); // good
The problem is that you are not providing a buffer for _tgetcwd to put its data into and _tgetcwd uses malloc() to allocate the buffer. You therefore need to use free() to free it up rather than delete[].
KString CFile::FileDirectory( _tgetcwd(NULL,MAX_PATH), true ); // bad
KString CFile::FileDirectory( _T("") ); // good
The problem is that you are not providing a buffer for _tgetcwd to put its data into and _tgetcwd uses malloc() to allocate the buffer. You therefore need to use free() to free it up rather than delete[].
Here's a fix:
KString CFile::FileDirectory( _tgetcwd(new wchar_t[MAX_PATH],MAX_PATH ), true ); // Should work
Because this provides a buffer using new[], your delete[] should be OK.
KString CFile::FileDirectory( _tgetcwd(new wchar_t[MAX_PATH],MAX_PATH
Because this provides a buffer using new[], your delete[] should be OK.
ASKER
No it isn't ... It still keeps crashing on me :S "invalid access to memory location"
And I'm pretty sure it is with that because that's the only change I made (and before that I could run it perfectly with regsvr32.exe).
And I'm pretty sure it is with that because that's the only change I made (and before that I could run it perfectly with regsvr32.exe).
Just to check that it was the only change made, can you re-confirm that changing it back to...
KString CFile::FileDirectory( _T("") );
....works?
KString CFile::FileDirectory( _T("") );
....works?
ASKER
sure thing... But it seems to be something with the constructor in KString that doesn't seems right...
Then try...
KString CFile::FileDirectory(L"");
...to use the wchar_t* constructor without the delete[].
You might also put some MessageBox's in there to see where is goes kaboom.
KString CFile::FileDirectory(L"");
...to use the wchar_t* constructor without the delete[].
You might also put some MessageBox's in there to see where is goes kaboom.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
G00fy, for the sake of the PAQ, was it the case that MAX_PATH was too small? Or did you use free? Or did it become OK, when you used static allocation, but you are not sure why?
rstaveley,
I agree. G00fy should provide some sort of insight.
My post did, after all, provide three suggestions. It is highly probable that the snippet of source code (static allocation worked). This would suggest that MAP_PATH is indeed sizeable enough. Which leads to the question - why did your snippet not do what it's [correctly] written to do?
>KString CFile::FileDirectory( _tgetcwd(new wchar_t[MAX_PATH],MAX_PATH ), true );
Hopefuly G00fy can indeed provide some insight.
I agree. G00fy should provide some sort of insight.
My post did, after all, provide three suggestions. It is highly probable that the snippet of source code (static allocation worked). This would suggest that MAP_PATH is indeed sizeable enough. Which leads to the question - why did your snippet not do what it's [correctly] written to do?
>KString CFile::FileDirectory( _tgetcwd(new wchar_t[MAX_PATH],MAX_PATH
Hopefuly G00fy can indeed provide some insight.
G00fy,
you should give the points to rstaveley because he found your bug.
_ys_,
> If a bad_alloc exception is thrown, who's going to handle it? Unlikely, but still worth thinking about.
if you have no 512 bytes of memory left you can't handle exceptions. Then, the program and perhaps the computer are dead. ;-)
Regards, Alex
you should give the points to rstaveley because he found your bug.
_ys_,
> If a bad_alloc exception is thrown, who's going to handle it? Unlikely, but still worth thinking about.
if you have no 512 bytes of memory left you can't handle exceptions. Then, the program and perhaps the computer are dead. ;-)
Regards, Alex
Please don't think I was bothered about the points. It is not knowing that I don't like. I was always a Christmas present prodder :-)
ASKER
the problem with creating a new char is, what if the path is > MAX_PATH? (I know, it's strange, but not unthinkable!).
I granted the "correct answer" to ys because he put me on the right way.
I have now in my cpp:
TCHAR szCwd[MAX_PATH+2];
KString CFile::FileDirectory( ConvertDirectory(szCwd) );
This functions free's, delete's or does whatever is necessary to prevent crashes and memleaks.
BTW, with the new []-thing it didn't worked either... It must be some strange allocation/deallocation error when using delete [] or free in a statically called (and named) variable.
I tried it with a "extern KS..., true);" and that worked fine... (so I moved it out of the class).
I hope this answer helped you guys...
I granted the "correct answer" to ys because he put me on the right way.
I have now in my cpp:
TCHAR szCwd[MAX_PATH+2];
KString CFile::FileDirectory( ConvertDirectory(szCwd) );
This functions free's, delete's or does whatever is necessary to prevent crashes and memleaks.
BTW, with the new []-thing it didn't worked either... It must be some strange allocation/deallocation error when using delete [] or free in a statically called (and named) variable.
I tried it with a "extern KS..., true);" and that worked fine... (so I moved it out of the class).
I hope this answer helped you guys...
Thanks for feeding back, G00fy.
In restrospect, it should have used new TCHAR[] to ensure that char[] was allocated if _UNICODE was not defined rather than always allocating new wchar_t[]. Conceivably a non-UNICODE build could have had problems invoking delete[] on what it thought was a char array rather than a wchar_t array. Having said that, you should have got a compilation error if you compiled it for non-UNICODE, when _tgetcwd was substituted by _getcwd (rather than _wgetcwd) and _getcwd grumbled about the non char* parameter.
Assuming it compiled OK, I suspect that the new []-thing was tripped up by your MAX_PATH length CWD. Does this work?
KString CFile::FileDirectory(_tget cwd(new TCHAR[MAX_PATH+1],MAX_PATH ),true);
If this works, it validates the use of delete[] in your constructor, and we can put the whole thing to bed :-)
In restrospect, it should have used new TCHAR[] to ensure that char[] was allocated if _UNICODE was not defined rather than always allocating new wchar_t[]. Conceivably a non-UNICODE build could have had problems invoking delete[] on what it thought was a char array rather than a wchar_t array. Having said that, you should have got a compilation error if you compiled it for non-UNICODE, when _tgetcwd was substituted by _getcwd (rather than _wgetcwd) and _getcwd grumbled about the non char* parameter.
Assuming it compiled OK, I suspect that the new []-thing was tripped up by your MAX_PATH length CWD. Does this work?
KString CFile::FileDirectory(_tget
If this works, it validates the use of delete[] in your constructor, and we can put the whole thing to bed :-)
ASKER
No, that's my point ... it seems the delete[] in my constructor freaked out when registering the dll (it worked fine nevertheless because I already registered it before, and didn't changed anything unusual but that).
> freaked out when registering the dll
?? I'm not with you.
?? I'm not with you.
1. Why do you call regsvr32.exe? I don't see any registry code.
regsvr32 is to register OLE-Dlls or ActiveX-Controls that have some appropriate entry functions.
2. The only difference between woring and non-working is the statement with CFile::FileDirectory ? Or did i miss some difference? And CFile is your class, and not from MFC?
Regards, Alex