A question about deleting a native pointer
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 13 of 13

Thread: A question about deleting a native pointer

  1. #1
    Join Date
    Aug 2009
    Location
    Finally back in Alaska
    Posts
    141

    A question about deleting a native pointer

    Hello all,

    I have an interop class that wraps a native class. Everything works great except in one function in the native class:

    Code:
    public MyNativeClass{
    
        void NativeFunction(MyNativeClass* _val){
    
             .....
             .....
             delete _val;    <------whenever this delete is called I get the assert error
    
         }
    
         ~MyNativeClass(){
    
              //cleans up various resources, and does so correctly even when called from the above delete
    
         }    <-----however upon exit of the destructor I get the assert error only if called through the delete above
    
    };
    The native class works fine if deleted from anywhere else, this is the only function in the class that tries to delete a seperate instance of itself. The reason I did it this way was because the pointer which gets passed into the function is a return value from a function in the managed class, so there is no physical pointer that I can delete outside of it. Im still learning interop, and this seemed like it would be the easiest way to plug that leak (since the return value was not getting deleted). For example:

    Code:
    public ref class MyMangedClass{
    
    private:
    
         InternalNativePointer* _val;
    
         NativeClassPointer* MangedFunction(){
    
               MyNativeClass* _retval=new MyNativeClass();
    
              ......
              ......
    
              return _retval;
    
          }
    
          void AnotherManagedFunction(){
    
             InternalNativePointer->NativeFunction(ManagedFunction());      <-----the native pointer used in the native class comes from here
    
         }
    
    };
    The error I am getting is:

    Debug Assertion Failed!

    Expression _BLOCK_TYPE_IS_VALID(pHead->inBlockUse);

    I tried looking through the docs, but I am not understanding why it is erroring out, am I not allowed to delete a seperate instance of the class from within the class? As I mentioned, all the other calls to delete from outside of the class work fine, and even when the specific call in question is run, it goes through the destructor fine and cleans up all the resources as it should, and I set the pointers to those resources to zero afterwards.

    What am I doing wrong?

    Thanks in advance,

  2. #2
    Join Date
    Apr 1999
    Posts
    27,426

    Re: A question about deleting a native pointer

    Quote Originally Posted by AKRichard View Post
    The native class works fine if deleted from anywhere else, this is the only function in the class that tries to delete a seperate instance of itself. The reason I did it this way was because the pointer which gets passed into the function is a return value from a function in the managed class, so there is no physical pointer that I can delete outside of it.
    I have no idea what "interop" is, or what it has to do with properly handling the C++ free-store operators, new and delete.

    There is nothing new in your issue -- you have corrupted the heap or the pointer value is invalid.

    First, new returns a value. Is it the same value you're deleting? Not pointer, but value.

    All you're showing in your code is that you're using the same variable. That doesn't really mean anything -- you should be looking at the value that is being returned by new, and whether it is the same value you're using in the delete.

    If it is the same value, then you either corrupted the memory, the pointer was already deleted and you deleted twice, or you allocated in one heap and deallocated using another heap. In any event, usage of smart pointers removes this unnecessary back-and-forth you're doing now, since a smart pointer always cleans itself up automatically when there are no more references to it and goes out of scope.
    I tried looking through the docs, but I am not understanding why it is erroring out, am I not allowed to delete a seperate instance of the class from within the class?
    You can look through all the docs you want, but you won't find the issue until you debug your program. Again, your problem is not unique, it isn't a fault of the system so that it is documented somewhere, or anything of the sort. It is a programming error caused by mismanaging pointers and the heap.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; January 22nd, 2013 at 06:41 AM.

  3. #3
    ovidiucucu's Avatar
    ovidiucucu is online now Moderator/Reviewer Power Poster
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,021

    Re: A question about deleting a native pointer

    [ Moved thread ]
    Ovidiu Cucu
    "When in Rome, do as Romans do."
    Visit: Microsoft Virtual Academy
    Follow: https://twitter.com/#!/ovidiucucu
    My blog: http://codexpert.ro/blog/author/ovidiu-cucu/

  4. #4
    Join Date
    Aug 2009
    Location
    Finally back in Alaska
    Posts
    141

    Re: A question about deleting a native pointer

    There is nothing new in your issue -- you have corrupted the heap or the pointer value is invalid.
    I have checked to make sure the actual value of the pointer didnt change, and I know that the pointer hasnt been deleted yet, but I am not sure how to narrow the search for where the heap would become corrupted. I thought that since I only get an error whenever that specific pointer is deleted it would be some piece of code connected with this particular pointer but I am having a hard time finding what is causing the corruption.

    I found if I comment out that particular delete, the program will run as expected except it creates a memory leak. Is there a way to make the debugger break at the particular point that the heap becomes corrupted? or when a value that is supposed to be outside the scope of the pointer is accessed through the pointer? Usually if I screw up a piece of code such as writing pass the end of an array, Ill get an error about possible heap corruption (usually popping up when the array is deleted), but this is the first I am seeing this assert error, usually it says something like a breakpoint has been hit and informs me the heap may have been corrupted. Thats the reason I was looking through the docs, Im trying to find out why the program would throw the assert error instead of the other error in the hopes it would help me identify where exactly the problem is.


    You can look through all the docs you want, but you won't find the issue until you debug your program. Again, your problem is not unique, it isn't a fault of the system so that it is documented somewhere, or anything of the sort. It is a programming error caused by mismanaging pointers and the heap.
    I wasnt meaning to imply I thought it was a problem of the system, I allways immediately assume the mistake is mine. I am here trying to understand the nature of the particular error better because I have not been able to identify the problem yet. Thats why I allways start out in the docs.

    I think I may know where the problem is, but am not sure how to make sure of it. I have the math stuff in assembly language. In the assembly language (the asm file) I have a strcuture that reflects the layout of the native class so that I can pass a pointer to the native class into the assembly language routines and be able to use the pointers to reach the members of the class. The particular algorithm returns a pointer to an instance of the structure for the return value. The problem may be in how I am creating the assembly version of the native class. the native class looks like this:

    Code:
    class NativeClass{
    
         unsigned __int64* _sign;
         unsigned __int64* _number;
    
    }
    and the assembly structure looks like this:

    Code:
    BI				struct
    
    	_sign				qword		0
    	_num				qword                   0
    		
    BI				ends
    in the assembly language code I create 3 pointer variables one to represent the _sign pointer, one to represent the _number pointer, the third one is to represent the "this" pointer which just has the first two pointers as the two elements. When the algorithm returns this structure both the native c++ and the managed c++ use the structure just like it would as if it had been created through the "new" operator. When I access the variables within it I get the correct results and it gives me access to the functions of the class, but I have to wonder if this is the problem within my code. I am not sure of the structure of the "this" pointer in c++, from investigating it under assembly language, the "this" pointer just appears to be an array of pointers to the variables of the class and this is what I was trying to duplicate. I have been talking about this framework for my algorithms in the assembly language forum, and they have helped me to get it this far, but I am being told that what I am doing is rather advanced and they werent sure about how to implement it but they were willing to learn with me.

    Anyways, because it doesnt error out till the destructor exits, and the destructor only frees the two pointers of the class (and does that correctly) Im wondering if it is having trouble freeing the "this" pointer I created (which I do not address in the destructor). If my implementation is incorrect then what is the nature of the "this" pointer? How does c++ handle freeing the "this" pointer? I know that whenever you use an instance of a class as a return value or when you pass one in, what you are actually getting is a "this" pointer to that instance of the class, all the documentation on msdn says this and the disassembly of code reflects this, but am I missing something? or should I be looking in a different part of the code for the problem?

    Thanks,

    Richard

  5. #5
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,583

    Re: A question about deleting a native pointer

    Your destructor is responsible for releasing resources your object allocated itself explicitly, but not for de-allocating the object (*this) itself. And generally, it isn't able to properly do that anyway, since your object doesn't know how it was allocated: dynamically using new or malloc() (and which one of the two), automatically on the stack or statically. (There are exceptions to this, however, for instance when you can guarantee that objects of that type have always been allocated using new, in which case a statement like delete this; is perfectly fine, but only as long as that guarantee holds true. Also, of course, the delete this; must not be inside the destructor, which would lead to infinite "deletion recursion" or something just about as creepy, instead it would call the destructor from another member function.)

    There's another scenario that may cause a program failure like this, that Paul didn't mention, probaly because that happens rather rarely: The object hasn't been allocated dynamically at all, and that's what I suspect is happening in your case, from what I recall from our discussions in the assembly section. So the most important question probably is: How did you allocate the object in question? Note that the C++ delete statement is not easily mappable to a single memory release runtime routine you can call from your assembly code. Also, I can't recall having seen any dynamic memory allocation calls in your assembly code at all anyway.

    What's happening when your destructor returns, in case it was invoked as the consequence of executing a delete statement, is not just a plain function return sequence. This also is the point when the compiler-generated code to de-allocate your object's memory is executed. And a crash like you describe it at this point is very likely an indication of any of the program malfunction types pointed out by Paul, or the extra one I added.

    Finally, I suggest you really make sure you're not returning a pointer to an object that may go out of scope while the pointer is still in use, as already pointed out in our assembly section discussions.

    Quote Originally Posted by AKRichard View Post
    I am not sure of the structure of the "this" pointer in c++, from investigating it under assembly language, the "this" pointer just appears to be an array of pointers to the variables of the class [...].
    The this pointer as such is just a single pointer, no more, no less. And what it points to is the binary in-memory representation of your object, consisting of the fields you declared for your object, not an array of pointers to these fields. However, the fact that your concrete object here exclusively consists of fields that are pointers may give rise to some confusion out the latter point.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  6. #6
    Join Date
    Aug 2009
    Location
    Finally back in Alaska
    Posts
    141

    Re: A question about deleting a native pointer

    So the most important question probably is: How did you allocate the object in question? Note that the C++ delete statement is not easily mappable to a single memory release runtime routine you can call from your assembly code. Also, I can't recall having seen any dynamic memory allocation calls in your assembly code at all anyway.
    in this particular instance I found out the only way this piece of code ever gets hit is if the object being deleted was created in the assembly routine. The reason why you never saw the allocation was because I created a routine (in the assembly language section) to create the object. It is created dynamically since I dont know ahead of time how big to make the array. The object is created through 3 calls to malloc, as mentioned above the first call represents the _sign pointer, the second represents the _number pointer, and the third is the one that represents the this pointer. When I built the object like this in the assembly routine and returned the created object to native/managed c++, the c++ side was reading the object fine as if it had been created with the "new" operator, giving me access not only to the internal variables (both pointers) but also to the functions and properties of the class.


    The this pointer as such is just a single pointer, no more, no less. And what it points to is the binary in-memory representation of your object, consisting of the fields you declared for your object, not an array of pointers to these fields.
    Ive been trying to find more info into the nature of the "this" pointer. Once the object I create is back in the c++ code, I have access to the various fields AND functions and properties, but in the assembly code, I only have access to the fields, which leaves me to believe that the clr/crt maps a vtable to the object somehow, but I am not sure how it associates that vtable to the object. I can reach the functions and properties of the native class through the assembly code, but not in the context of a particular instance of the object. This also applies to instances of the native class passed into the assembly code that were created with the "new" operator thats why I mentioned I believe it is happening in the clr/crt. This is not a problem in my code, I only mention it because if I am not creating an instance of the "this" pointer that the clr/crt can understand, then it makes sense that it also wont know how to clean up the "this" pointer. After saying all this, I am thinking maybe I should try cleaning it up in the assembly code, instead of using "delete" maybe I should be calling the cleanup routine I have in assembly that I use whenever a temporary instance is created in one of the assembly language routines. Even if that works though, it seems the appropriate way would be to make sure the object created and returned by assembly code follows the rules of an object created through "new" under the clr/crt so that it could be destroyed with "delete".

    Just for clarity, I know the clr uses "gcnew" for managed objects, what I am trying to follow would be just the native use of "new" and "delete"
    Last edited by AKRichard; January 23rd, 2013 at 01:03 AM.

  7. #7
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,583

    Re: A question about deleting a native pointer

    Ok, let's start at the end of your post...

    Quote Originally Posted by AKRichard View Post
    Just for clarity, I know the clr uses "gcnew" for managed objects, what I am trying to follow would be just the native use of "new" and "delete"
    That's how I was already understanding it. We're talking about a native object here, and the CLR may deal with the object in several ways, including allocation and deallocation, but it may not change the nature of the object itself, because that would instantly make the object unusable on the native side, thereby spoiling the whole purpose of interop. So, as long as your native object doesn't in turn reference any managed objects, what your object fortunately doesn't, we should be able to safely ignore the CLR entirely with respect to the problem discussed here. (As a consequence, except for the plainly absurd candidates like the scripting section, ths forum section here probably is the least appropriate place for this thread. However, this sort of confusion simply can happen with interop topics and somewhat is by its nature... )

    Quote Originally Posted by AKRichard View Post
    [...] The object is created through 3 calls to malloc, as mentioned above the first call represents the _sign pointer, the second represents the _number pointer, and the third is the one that represents the this pointer. When I built the object like this in the assembly routine and returned the created object to native/managed c++, the c++ side was reading the object fine as if it had been created with the "new" operator, giving me access not only to the internal variables (both pointers) but also to the functions and properties of the class.
    The plain truth here is that an object allocated using malloc() must not be released using delete; you must use free().

    I have seen quite some extensive discussions about whether, in practice, one might get away with that, or with releasing an array of objects allocated using new [] with a plain delete. The bottom line of all these discussions is that one may get away with this if the objects dealt with don't have any constructors nor destructor (not even implicitly generated ones), which is particularly true for POD objects. But that heavily depends on implementation details of both the compiler and the runtime. Of course, relying on this, frankly speaking, undefined behavior to behave in any deterministic way is big-time haphazard and better shouldn't be done at all.

    In our specific scenario here, it can't even be safely expected that this implementation detail behaves consistently between the x64 and x86 versions of the MS compilers, so I can't run any meaningful (for your concrete scenario) tests here.

    Of course you want your client code to be able to handle your objects as real C++ objects, using new and delete rather than malloc() and free(). I see some alternative approaches to that which all rely on your native C++ object encapsulating your assembly language implementation:
    • Simply don't use malloc() to allocate the objects exposed to client code; only use new. The numeric representation arrays your object points to can be treated as implementation details which the client code isn't supposed to allocate or deallocate, so you can use malloc() and free() for them, but of course consistently. This is the simplest approach but may not easily be possible, depending on your design.
    • Use the pimpl idiom and exclusively allocate/deallocate the implementation objects using malloc()/free(), just like the numeric representation arrays.
    • Define a static Create() method (or some overloads of it, taking different parameters) in your native C++ class that is to be called from the assembly language routines and returns a pointer to a readily allocated and set-up object, using new of course. (Be aware of name magling, see below.) This may be one advanced way to implement option #1.


    Ive been trying to find more info into the nature of the "this" pointer. Once the object I create is back in the c++ code, I have access to the various fields AND functions and properties, but in the assembly code, I only have access to the fields, which leaves me to believe that the clr/crt maps a vtable to the object somehow, but I am not sure how it associates that vtable to the object.
    Instances of casses without virtual functions don't have a vtable. It's not that complicated.

    I can reach the functions and properties of the native class through the assembly code, but not in the context of a particular instance of the object. This also applies to instances of the native class passed into the assembly code that were created with the "new" operator thats why I mentioned I believe it is happening in the clr/crt.
    The CLR isn't involved here (see beginning of the post). It's just the way instance methods of C++ classes are called. Practically invisible at the source code level, instance methods get passed the this pointer as a hidden first parameter. That way the generated machine code inside gains access to the oject it is called on. Being aware of that, you can call instance methods from assembly language routines as well. I don't know details of how that's done in x64, but that's a pointer for further research for you.

    Also, C++ uses mangled function names at the oject file level, leading to names that are somewhat obfuscated. These are the names you'd access them under from assemly language. The purpose of name mangling is to not only encode the function name itself, but also the class it's a member of and its signatore (return type and types of parameters), thereby enabling the definition of multiple overloads of a single function name. Name mangling is implementation-specific AFAIK, so I can't tell you much about how the x64 compiler handles it. Perhaps you're lucky and can find (or already have as part of your installation) a tool to convert C++ .h files to assembly language include files. That would take care of the name mangling for you, and I'm quite certain I've already seen something like that, at least for x86.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  8. #8
    Join Date
    Aug 2009
    Location
    Finally back in Alaska
    Posts
    141

    Re: A question about deleting a native pointer


    •Define a static Create() method (or some overloads of it, taking different parameters) in your native C++ class that is to be called from the assembly language routines and returns a pointer to a readily allocated and set-up object, using new of course. (Be aware of name magling, see below.) This may be one advanced way to implement option #1.
    I just so happen to be working on this very approach right now, fell asleep at the computer last night in the middle of it. I started thinking I could make a Create and a Destroy functions to be called from the assembly language code. This will lead to a lot of back and forth code dropping between the native c++ and assembly code, but I havent noticed a lot of overhead for that transition like I did between managed and native c++.


    Also, C++ uses mangled function names at the oject file level, leading to names that are somewhat obfuscated. These are the names you'd access them under from assemly language.
    Ive been using dependency walker to look at the name mangling after the code is compiled for this very reason. I have a few functions in native c++ that I call from the assembly code (usually for debugging purposes). Its also this that I was having a problem with, I had tried calling the constructors to the native c++ class thinking it would return a pointer to a new object, but it didnt work the way I thought it would and have not been able to figure out why. I had just thought about using a special method in the native c++ code to create a new instance and return a pointer to it, but thought Id check on this thread before going back to it.


    The plain truth here is that an object allocated using malloc() must not be released using delete; you must use free().
    in the destructor in the native c++ object, the two pointers are freed through the assembly code depending on how they were allocated. I have a few global variables in the assembly code that control how memory is allocated (through my own mem management routine or with malloc) and the assembly routine takes care of freeing the memory depending on how it was allocated. This does not address the "this" pointer part of it though, and I am sure this is where my problem is now.


    (As a consequence, except for the plainly absurd candidates like the scripting section, ths forum section here probably is the least appropriate place for this thread. However, this sort of confusion simply can happen with interop topics and somewhat is by its nature... )
    When I posted the question I was thinking it was an interop problem since it only appeared directly after a managed object deleted a native object (thereby starting the managed to native transition), it wasnt until I finally made some headway debugging that I came to the realization that it is probably in how I was creating the object in assembly language. This is the reason why I use the CodeGuru forums more than any other, instead of trying to fix the problem for me yall give me alternate ways to think of the problem and info to help me towards the solution

  9. #9
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,583

    Re: A question about deleting a native pointer

    Quote Originally Posted by AKRichard View Post
    [...] I started thinking I could make a Create and a Destroy functions to be called from the assembly language code. [...]
    You probably already considered this, yet a word of caution: If the Destroy() method shall contain a delete this; statement, of course the method must only be called on objects that have been allocated using new, otherwise you'd be getting back to just the same trouble you're solving now. Also, except in some rare scenarios involving local variables or parameters passed to the Destroy() method, the delete this; should be the last statement in the method, since after that the object is in an invalid/undefined state.

    [...] I had tried calling the constructors to the native c++ class thinking it would return a pointer to a new object, but it didnt work the way I thought it would and have not been able to figure out why. [...]
    Just like the destructor doesn't know how it has been allocated, the constructor has no idiea how it is to be allocated. Instead it's new that does the allocation and passes the pointer to the allocated memory block to initialize it and turn it into a valid object. (I'm unsure about how the pointer is passed, even more so in x64, but I suppose it works much like passing the this pointer to instance methods; after all it is the this pointer...) Alternatively, the object may have been allocated using any of the non-dynamic ways; that's transparent to the constructor.

    There also is the rarely used placement new that you may already have heard of, to which you pass the pointer to the memory block to initialize explicitly. One of its uses happens to be initializing objects that have been allocated via malloc().

    [...] I have a few global variables in the assembly code that control how memory is allocated (through my own mem management routine or with malloc) and the assembly routine takes care of freeing the memory depending on how it was allocated. [...]
    Just as a marginal comment: As a diagnostic feature, I'd have probably implemented that using preprocessor conditionals, that way making the decision at compile-time so that the final compilation result would only contain one of the two variants. (I suppose there's an equivalent to those directives in x64 assembly; at least I'm rather sure there is in x86.)

    [...] This does not address the "this" pointer part of it though, and I am sure this is where my problem is now.
    The placement new mentioned above could be part of the solution to that. That would somewhat shift the appeal of the code towards low-level, but I don't think one who writes assembly language would really be concerned about that...

    When I posted the question I was thinking it was an interop problem since it only appeared directly after a managed object deleted a native object (thereby starting the managed to native transition), it wasnt until I finally made some headway debugging that I came to the realization that it is probably in how I was creating the object in assembly language. This is the reason why I use the CodeGuru forums more than any other, instead of trying to fix the problem for me yall give me alternate ways to think of the problem and info to help me towards the solution
    Well, from my current state of knowledge, since the discussion touches compiler/runtime implementation details, the best place for the thread IMO would be the VC++ section, which just happens to be where you started it... OTOH, up to now, implementation details have just been touched peripherically and treated as an abstract black box (which is how they usually should be treated), so the Non-VC++ section may be a good place too.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  10. #10
    Join Date
    Aug 2009
    Location
    Finally back in Alaska
    Posts
    141

    Re: A question about deleting a native pointer


    You probably already considered this, yet a word of caution: If the Destroy() method shall contain a delete this; statement, of course the method must only be called on objects that have been allocated using new, otherwise you'd be getting back to just the same trouble you're solving now
    there is no delete this;, but the destroy method takes an instance of the class as a parameter and there is a delete _val; which is working as expected.


    There also is the rarely used placement new that you may already have heard of, to which you pass the pointer to the memory block to initialize explicitly. One of its uses happens to be initializing objects that have been allocated via malloc().
    When working on figuring out how to make it work, I would set a break point at the creation of a new object and step through the disassembly to see how it was being done, there were a couple of different paths that it could take with names like _newh and stuff, while I stepped through it though it allways took the first path, which would create an array of 2 elements and store the pointer to _sign in the first, and the pointer to _num in the second (exactly as I was trying to do), but in the disassembly routine it uses a Security_Descriptor for some purpose I havent been able to figure out yet, (which I think is where my problem came in).

    As a side note, stepping through the disassembly I noticed the code was very ineffecient in some ways doing things like:

    Code:
    mov     [rsp+8], rax
    mov     rax, [rsp+8]
    there should be no need for the second move instruction, but I see that very sequence all over the place in the disassembly window.


    Just as a marginal comment: As a diagnostic feature, I'd have probably implemented that using preprocessor conditionals, that way making the decision at compile-time so that the final compilation result would only contain one of the two variants. (I suppose there's an equivalent to those directives in x64 assembly; at least I'm rather sure there is in x86.)
    I switch between the two during runtime sometimes, my memory management runs quite a bit faster in a single threaded app, but I am still working out the kinks in multithreaded mode, so for right now, if it starts being called from multiple threads it drops back to using malloc. Ive got the free routine able to handle the switch at anytime now. When I figure out how to get around the bottleneck I dont expect to use malloc any more.


    Well, from my current state of knowledge, since the discussion touches compiler/runtime implementation details, the best place for the thread IMO would be the VC++ section, which just happens to be where you started it... OTOH, up to now, implementation details have just been touched peripherically and treated as an abstract black box (which is how they usually should be treated), so the Non-VC++ section may be a good place too.
    lol I didnt expect this thread to go down this road but the good news, after I run through my tests, if I dont have anymore questions on the subject, Ill be marking it as solved.

    You know, if I ever distribute this set of libraries, Im going to have to give you credit in it. Youve actually helped me figure out the more difficult aspects of it.

  11. #11
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,583

    Re: A question about deleting a native pointer

    Quote Originally Posted by AKRichard View Post
    there is no delete this;, but the destroy method takes an instance of the class as a parameter and there is a delete _val; which is working as expected.
    Then it's a static method? Technically that's pretty much the same as a parameterless instance method, mostly making a stylistic difference.

    When working on figuring out how to make it work, I would set a break point at the creation of a new object and step through the disassembly to see how it was being done, there were a couple of different paths that it could take with names like _newh and stuff, while I stepped through it though it allways took the first path, which would create an array of 2 elements and store the pointer to _sign in the first, and the pointer to _num in the second (exactly as I was trying to do) [...].
    Can't say anything about the other paths, of course, but what you describe here looks like the inlined constructor code to me.

    [...] but in the disassembly routine it uses a Security_Descriptor for some purpose I havent been able to figure out yet, (which I think is where my problem came in).
    I have seen things like that in my x86 code as well, and per my experience they don't interfere with my code as long as I do things properly. They may probably drain a bit of performance and there may be the possibility of removing them by tweaking compiler options, but I never really bothered to research the details.

    As a side note, stepping through the disassembly I noticed the code was very ineffecient in some ways doing things like:

    Code:
    mov     [rsp+8], rax
    mov     rax, [rsp+8]
    there should be no need for the second move instruction, but I see that very sequence all over the place in the disassembly window.
    Is this from the JIT-compiler output originating from managed code? I see sequences of that kind all over the place in the IL generated by the C++/CLI compiler and was hoping the JIT compiler would optimize them out . However, I don't think it incurs a significant performace drain, since the data qword is guaranteed to be in the cache when the second instruction gets executed (except perhaps the thread's timeslice happens to end just between these two instructions, which is rather unlikely), or even the CPU is clever enough to detect the redundancy and cut some corners. At any rate, if it did significantly impair performance, I'm confident MS would have made the JIT compiler optzimize them out. ... at least I hope so...

    I switch between the two [memory management modes] during runtime sometimes, my memory management runs quite a bit faster in a single threaded app, but I am still working out the kinks in multithreaded mode, so for right now, if it starts being called from multiple threads it drops back to using malloc. Ive got the free routine able to handle the switch at anytime now. When I figure out how to get around the bottleneck I dont expect to use malloc any more.
    Doesn't that incur the risk of releasing objects that were allocated before the switch the wrong way?

    You know, if I ever distribute this set of libraries, Im going to have to give you credit in it. Youve actually helped me figure out the more difficult aspects of it.
    Yo, thanks!
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  12. #12
    Join Date
    Aug 2009
    Location
    Finally back in Alaska
    Posts
    141

    Re: A question about deleting a native pointer


    Then it's a static method? Technically that's pretty much the same as a parameterless instance method, mostly making a stylistic difference.
    Yes, I made all the Create and the one Destroy methods static.


    I have seen things like that in my x86 code as well, and per my experience they don't interfere with my code as long as I do things properly. They may probably drain a bit of performance and there may be the possibility of removing them by tweaking compiler options, but I never really bothered to research the details.
    I dont think that it is slowing my code at all, just mentioned it because I really didnt understand what it was doing, the rest of the code was pretty self explanatoy after running through it a few times.


    Is this from the JIT-compiler output originating from managed code? I see sequences of that kind all over the place in the IL generated by the C++/CLI compiler and was hoping the JIT compiler would optimize them out . However, I don't think it incurs a significant performace drain, since the data qword is guaranteed to be in the cache when the second instruction gets executed (except perhaps the thread's timeslice happens to end just between these two instructions, which is rather unlikely), or even the CPU is clever enough to detect the redundancy and cut some corners. At any rate, if it did significantly impair performance, I'm confident MS would have made the JIT compiler optzimize them out. ... at least I hope so...
    Id imagine its from the jit compiler, I was running the release version in the visual studio debugger. And youre probably correct about the cpu optimizing it away, Id imagine the only place it would make a difference is taking space in the execution pipeline. I dont really see it making that much of a difference in execution time, it just looks funny. But then the jit maybe smart enough to be putting that code in on purpose, I know you can get more efficiency out of the cpu by putting certain types of instructions next to each other, Ive read about optimizing to that level, thats rather outside of my experience though. It just looks funny to me.


    Doesn't that incur the risk of releasing objects that were allocated before the switch the wrong way?
    No, the way I have it set up, my memory management routine gets a chunk of memory (about 1.5 megs) and dolls out chunks from that, so whenever the program is returning the memory, it checks the memory being returned address against the memory I am handing out from, if it is in that range, then the routine simply marks the chunks as unused, if it is outside of that range it sets it up for a call to free. I can switch between the methods in the middle of a running program with a bunch of variables allready using memory I handed out and it will seamlessly free the memory correctly. It only takes some dozen or so instructions to figure it out, but as I mentioned, when I figure out how to get through the bottleneck in multi-tthreaded mode, Ill be using my memory exclusively. If Im having a hard time debugging a section, Ill usually set it up to use malloc with the usumption that whatever the problem is it wont be coming from memory management then.


    Yo, thanks!
    No prob. I dont have any plans on trying to distribute it, but I find these libraries more usefull then any of the other bignumber libraries out there. They work great in my encryption, scientific, and general math programs I play with. But if I ever do distribute it, Ill be asking if you want your name in it or not.

  13. #13
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,583

    Re: A question about deleting a native pointer

    Quote Originally Posted by AKRichard View Post
    [...] But then the jit maybe smart enough to be putting that code in on purpose, I know you can get more efficiency out of the cpu by putting certain types of instructions next to each other, Ive read about optimizing to that level, thats rather outside of my experience though.
    I know these techniques. The early Pentium processors didn't support out-of-order execution, so they were crucial to get decent performance out of them by placing independent instructions next to each other and keep both pipelines busy. The VC++6 compiler was quite good at that, but it resulted in machine code output hardly comprehensible by humans. But this sort of optimization never deliberately generated entirely redundant instructions. Also, in the two instructions we're discussing here, the second one depends on the first one as much as can do (except that it's totally redundant, of course).

    The JIT compiler isn't exactly generating these redundant sequences, it just translates them from the IL instructions it gets from the compiler, where they look like this:

    Code:
      IL_0010:  stloc.0
      IL_0011:  ldloc.0
    Ok, the virtual CPU executing the IL uses an operand stack instead of general-purpose registers, and the stloc instruction "consumes" (i.e. pops) the value it stores, but if the sequence was meant to store the value on the stack for later use, then chances are this would be a bit more efficient:

    Code:
      IL_0010:  dup
      IL_0011:  stloc.0
    And sequences like that sometimes obviously don't serve the purpose of effectively storing data for later use. For instance they may be found right before a ret instruction, and the local variable even may have been created exclusively to serve the sequence. However, sequences like that right before a ret may be a phenomenon exclusively found in debug builds; at least I didn't see any of them when brousing through a release compilation result while writing this post.

    But then again, .NET hasn't really been made for people who are seriously concerned about so tiny bits of performance anyway...
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Azure Activities Information Page

Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center