|
You can count on proper behavior of T() when T is simple type. This applies to this map situation.
To have even more fun, check the following declarations - they'll work:
int i = int();
typedef char *pchar;
pchar pc = pchar();
Tomasz Sowinski -- http://www.shooltz.com
Free your mind and your ass will follow.
|
|
|
|
|
So simple types (int, float?, double, char etc) are all initialized to 0 ? Very cool but I had always been told that C/C++ did not initialize primitive types, although I suppose this case is a bit different.
Good to know anyways ! Thanks
Do you know if this works on GCC ? I take it that it is part of the C++ standard right ?
|
|
|
|
|
Jim Crafton wrote:
So simple types (int, float?, double, char etc) are all initialized to 0 ?
Not exactly. When you're declaring an int without initializer, you'll get random bits:
int x;
However, you can initialize variable with constant, or with this pseudo-constructor syntax:
int x = 5;
int y = int();
int z = int(3);
Jim Crafton wrote:
I take it that it is part of the C++ standard right ?
I guess it is. Otherwise standard containers would have hard time working with ints and doubles. In the STL sources there are many T t = T() constructs which have to work OK with simple types.
Tomasz Sowinski -- http://www.shooltz.com
Free your mind and your ass will follow.
|
|
|
|
|
My company has a code library (dll) we release to customers. We'd like to only release the RELEASE version and not the DEBUG version to the customer. The problem is that one of the classes in the library automatically deletes some classes that can be allocated by the customer using the library with new.
When the customer links to our RELEASE builds within his DEBUG build it causes exceptions like "Invalid Address specified to RtlFreeHeap".
I assume that it's because the customer allocated an object with new in his DEBUG code and we free'd it with delete in our RELEASE code.
I know there has to be a way to handle this as I'm sure alot of companies sell RELEASE ONLY dlls to customers. How is this accomplished to allow the user to build DEBUG versions against your release DLLs?
Another note is that the DLL is a non-MFC dll which is linking to an MFC app usually.
Thanks for any help.
|
|
|
|
|
If your design requires freeing things allocated in customers code, you have to provide both debug and release build. And - your customers are forced to use DLL version of C runtime.
You may consider exposing some allocator object or allocating objects at the .dll side.
Tomasz Sowinski -- http://www.shooltz.com
Free your mind and your ass will follow.
|
|
|
|
|
You could get your users to build in release mode but use debugging info in their app so its almost the same as regular debugging.
Roger Allen
Sonork 100.10016
I think I need a new quote, I am on the prowl, so look out for a soft cute furry looking animal, which is really a Hippo in disguise. Its probably me.
|
|
|
|
|
i'd never use a library that made me do that.
-c
Aiei i ea eio aoa i e eio e aigoa
|
|
|
|
|
Well, its only a suggestion.
Roger Allen
Sonork 100.10016
I think I need a new quote, I am on the prowl, so look out for a soft cute furry looking animal, which is really a Hippo in disguise. Its probably me.
|
|
|
|
|
do your customers have to use the objects allocated inside your DLL? some of my DLLs allocate objects and pass them back to the caller, but the caller never has to do anything with the object, except pass it back into the DLL. also, i always pass the objects back as "void *" so there's never even any temptation by the caller to do anything with the object. any manipulation and clean-up of these objects is handled by functions inside the DLL, so there's no chance of mixing debug/release code.
-c
Aiei i ea eio aoa i e eio e aigoa
|
|
|
|
|
Yes, they do.
The problem area is a custom linked list we've implemented that holds pointers to custom objects. The users allocate the custome objects then add them to the custom linked list. This custom linked list automatically cleans up the objects they allocated when the list goes out of scope.
So, they may or may not use the object that they allocate.
|
|
|
|
|
Are custom objects derived from common base class defined in your .dll? If this is the case, just add abstract Delete() method. Trivial implementation in users's code just calls 'delete this'.
Tomasz Sowinski -- http://www.shooltz.com
Free your mind and your ass will follow.
|
|
|
|
|
That's the problem. The user can't delete the object as the list does it for them. The user allocates the object, but NEVER deletes it. The list does.
|
|
|
|
|
The trick I've described in previous post would work. The only prerequisite is that objects in the list are derived from class defined in .dll.
Tomasz Sowinski -- http://www.shooltz.com
Free your mind and your ass will follow.
|
|
|
|
|
Ahh, I think I get it.
Yes, all the custom objects are derived from a base class that's in the DLL.
So, You're saying that I can just override the ::delete operator in the base class. That way the object is always deleted from the DLL?
Is that correct?
|
|
|
|
|
SchmoBoy wrote:
You're saying that I can just override the ::delete operator in the base class
Actually, I wasn't referring to this solution. I'm not sure if you can achieve your goal with overriding delete operator (note that you'd have to override new as well). Give it a try, if it's not possible, consider the following:
I'd add special abstract method in base class:
class BaseClassInDll
{
public:
...
virtual void DeleteMe() = 0;
};
Your list would call obj->DeleteMe() instead of delete obj. Users of your .dll would have to provide the implementation of DeleteMe. Implementation is trivial, it's just 'delete this' statement:
class DerivedInExe : public BaseClassInDll.
{
public:
...
virtual void DeleteMe() { delete this; }
};
Basically, this provides sort of callback into EXE available from DLL.
Tomasz Sowinski -- http://www.shooltz.com
Free your mind and your ass will follow.
|
|
|
|
|
Well, Tomasz headed me in the right direction...
The solution is to overload the ::new and ::delete operators so ALL memory allocation and deallocation are routed through the DLL. In the base class I simply added the following functions. Note the three parameter new and delete are required as MFC uses these calls for tracing, etc. So I just included both to work with and without MFC/Win32.
<br />
void * CMPI_Obj::operator new(size_t sizeofRow)<br />
{<br />
void* p = new char[sizeofRow];<br />
<br />
return memset(p, 0, sizeofRow * sizeof(char));<br />
} <br />
<br />
void * CMPI_Obj::operator new(size_t sizeofRow, LPCSTR lpszFileName, int nLine)<br />
{<br />
void* p = new char[sizeofRow];<br />
<br />
return memset(p, 0, sizeofRow * sizeof(char));<br />
} <br />
<br />
void CMPI_Obj::operator delete(void *ptr)<br />
{<br />
::delete ptr; <br />
}<br />
<br />
void CMPI_Obj::operator delete(void* ptr, LPCSTR lpszFileName, int nLine)<br />
{<br />
::delete ptr; <br />
}<br />
<br />
Thanks for everyone's help and suggestions. I think I've found the most elegant solution where we can still JUST ship RELEASE and the customer can still build DEBUG against it.
|
|
|
|
|
I don't have any reference book at hand right now, but make sure you have operator new for arrays as well.
Tomasz Sowinski -- http://www.shooltz.com
Free your mind and your ass will follow.
|
|
|
|
|
Yes, you are correct. new[] and delete[] are needed. I forgot those in the code snippet above.
|
|
|
|
|
could you make them provide a callback function for your DLL to use that would handle de-allocation?
ie. they write a function that like this:
BOOL CALLBACK MyFree(Object *p)
{
delete p;
return TRUE;
}
and your code would do:
// time to delete this
(*CallerFree)(pObject);
that way, the delete used will always be the correct one.
-c
Aiei i ea eio aoa i e eio e aigoa
|
|
|
|
|
Chris Losinger wrote:
Aiei i ea eio aoa i e eio e aigoa
"Yesterday was oil now it is oil and water"
Anche tu parla Spezzino ?!
Concussus surgo.
When struck I rise.
|
|
|
|
|
Daniel Turini wrote:
Anche tu parla Spezzino ?!
no
i just like the fact that the sentence has only one consonant.
-c
Aiei i ea eio aoa i e eio e aigoa
|
|
|
|
|
we had the same issues
My solution was to release 2 forms of the lib both with the .lib and .dll files
The first was the standard release build
the second was a "fake" debug build,
in the C++ settings it had Optimizations turned on, and Debug info turned off. BUT in the COde Generation setion it used the Debug Multithreaded DLL libs as opposed to the Multithreaded DLL libs. The linker settings were the same as release - i.e. no debug info
This seemed to do the trick
If this is wrong please don't shoot me
|
|
|
|
|
I am attempting to create a doc/view application with dialog boxes. On startup, I am looking to launch a dialog box, once the view is created, to collect some information. I can easily create a function in the menu to do this, but I'd rather the dialog box launch automatically. How do I do this?
Thanks in advance.
|
|
|
|
|
Launch the dialog at the end of OnInitialUpdate.
Tomasz Sowinski -- http://www.shooltz.com
Free your mind and your ass will follow.
|
|
|
|
|
I tried to launch the dialog box at the end of OnInitialUpdate, in the View class, but it does not create the view first. Is there a function that is processed after the view and the doc class are created, as if a user selected FILE->LAUNCH? Thanks again for the comment.
Rich
|
|
|
|