Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode.
Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).
On 18/11/2013 at 13:42, xxxxxxxx wrote:
User Information: Cinema 4D Version: R9 - R15 Platform: Windows ; Mac ; Mac OSX ; Language(s) : C++ ;
--------- Howdy,
OK, in my attempt to keep my code backward compatible I've created lots of wrapper functions with preprocessor directives that check the API_VERSION and compile accordingly. This has been working beautifully in that I only code once and compile for all versions.
But with the memory allocation changes in R15, I've run into a small snag.
Here is my wrapper code for GeAlloc()/GeFree() and NewMemClear()/DeleteMem() :
template<typename T> T* CDAlloc(LONG s) { #if API_VERSION < 15000 LONG size = sizeof(T) * s; return (T* )GeAlloc(size); #else return (T* )NewMemClear(T,s); #endif } template<typename T> void CDFree(T* x) { #if API_VERSION < 15000 GeFree(x); #else DeleteMem(x); #endif }
... which seems to work except for an intermittent crash upon calling CDFree().
Is there something wrong with the above code?
Adios, Cactus Dan
On 18/11/2013 at 14:24, xxxxxxxx wrote:
my "guess" is that "NewMemClear" should be "NewMem" as the first one auto clears and doesn't need delete "but I'm noob so all of this may be wrong"
On 18/11/2013 at 14:25, xxxxxxxx wrote:
for safety , do : if (x) DeleteMem(x);
On 18/11/2013 at 14:43, xxxxxxxx wrote:
Howdy,
Well, I should have specifically mentioned that it is the versions prior to R15 that are crashing, in other words the call to CDFree() wrapped to GeFree().
In all areas where I'm calling that function, I'm calling it like this:
if(ptr) CDFree(ptr);
... which seemed fine when using GeFree() in the prior versions, but the wrapped version seems to cause an intermittent crash.
On 18/11/2013 at 15:37, xxxxxxxx wrote:
well not sure , but may be this is related "The other change is that while GeAlloc would return nullptr for size 0 , NewMem()/NewMemClear() will return a valid address (like malloc)."
GeAlloc
nullptr
malloc
On 19/11/2013 at 04:01, xxxxxxxx wrote:
Hi Dan,
I think you have missed only one & in CDFree(T* ptr) it must be CDFree(T*& ptr). CDFree() will also not only delete the memory but set ptr to nullptr.
template<typename T> T* CDAlloc(LONG s) { #if API_VERSION < 15000 LONG size = sizeof(T) * s; return (T* )GeAlloc(size); #else return (T* )NewMemClear(T,s); #endif } /// ptr can be nullptr. /// ptr will be set to nullptr after this call. template<typename T> void CDFree(T*& ptr) { #if API_VERSION < 15000 GeFree(ptr); #else DeleteMem(ptr); #endif }
Here is short test that work for me on R14.
Int32 *t = CDAlloc<Int32>(100); CDFree(t); CDFree(t); t = nullptr; CDFree(t);
Remo
On 19/11/2013 at 06:36, xxxxxxxx wrote:
Ah, so are you saying that adding the "&" references the original pointer, where as the way I have it now, it is only pointing to the original pointer, so GeFree() only sets the "pointer to a pointer" to NULL leaving the original pointer unchanged?
On 19/11/2013 at 07:39, xxxxxxxx wrote:
You won't need to wrap the GeAlloc()/GeFree() calls for R15 if you define the __LEGACY_API for the preprocessor.
Best, -Niklas
On 19/11/2013 at 07:43, xxxxxxxx wrote:
OK, it still crashes when running the debugger, but doesn't crash immediately with the release version.
Here's the test I did with R12 in the debugger:
LONG *n = CDAlloc<LONG>(100); CDFree(n); CDFree(n); // crash immediately in debbugger
So, I changed my CDFree() function to this:
template<typename T> void CDFree(T& ptr) { #if API_VERSION < 15000 GeFree(ptr); #else DeleteMem(ptr); #endif }
... and now it doesn't crash in the debugger.
Thanks Remo for pointing that out, otherwise I would never have thought to use the & operator.
On 19/11/2013 at 08:07, xxxxxxxx wrote:
Originally posted by xxxxxxxx You won't need to wrap the GeAlloc()/GeFree() calls for R15 if you define the __LEGACY_API for the preprocessor. Best, -Niklas
Originally posted by xxxxxxxx
Oh? I don't see GeAlloc()/GeFree() in the legacy.h file.
Besides, I couldn't get that to work, so instead, I simply copied the file, renamed it to "CDLegacy.h" removed the
#ifdef __LEGACY_API
...and included it in my R15 projects like this:
#if API_VERSION > 14999 #include "CDLegacy.h" #endif
To be honest, I'd have preferred the legacy.h file to have been the other way around (typing the new types to the old types), so that I could change all of my code to use the new R15+ types, and then include the legacy.h file with all the older version projects.
EDIT: Ah, OK, I see that GeAlloc()/GeFree() is in c4d_memory.h. But anyway, since I couldn't get the __LEGACY_API defined properly, my wrapper function will do fine. Not only that, but it was a good exercise in template programming.
On 19/11/2013 at 08:44, xxxxxxxx wrote:
^ I haven't touched any of the R15 stuff yet. And I probably won't for a while because I refuse to have VS2012 installed on my computer. But when Maxon eventually supports VS2013 natively without needing VS2012 installed. I will probably want to start using the new SDK. An when I do. The first thing I'm going to look for is a proper tutorial on setting up the __LEGACY_API stuff.
-ScottA
On 19/11/2013 at 08:50, xxxxxxxx wrote:
OK, just to double check, I set a couple of breakpoints in the debugger.
Breakpoint 1:
Breakpoint2:
As you can see at the first breakpoint the pointer "n" has a valid address and at the second breakpoint the pointer "n" has been set to NULL. So it's working fine. Thanks again Remo.