-1

If I have the following piece of code :

void foo (String^ v)
{
   WCHAR someString[256];
   _tcscpy_s(someString, (LPCTSTR)Marshal::StringtoHGLobalUni(v).ToPointer());
}

Would I still need to use FreeHGlobal() in this case? And if so, why? Would the copy function not take care of this global allocation?

user1173240
  • 1,455
  • 2
  • 23
  • 50

1 Answers1

2

Yes, FreeHGlobal is necessary. _tcscpy_s has no knowledge of where the buffer came from; it doesn't know to free the buffer.

If you wanted an automatic free, you'll want to use some object that is smart enough to do the free when it leaves scope. marshal_context is a good choice here.

void foo (String^ v)
{
    marshal_context context;
    WCHAR someString[256];
    _tcscpy_s(someString, context.marshal_as<const TCHAR*>( v ));
} // <-- The marshal_context, and the unmanaged memory it owns, 
  //     are cleaned up at the end of the function.

(Disclaimer: I'm not at a compiler, there may be syntax errors.)

David Yaw
  • 27,383
  • 4
  • 60
  • 93
  • Thanks a lot. I'll have a look at it. If I perform the operation, on a string being passed to another function, like, `someFunc((LPTSTR)Marshal::StringToGlobalUni(someManagedString).ToPointer());`, I suppose then it should be OK, since the operation would have been performed on a copy, and there's nothing to perform a FreeHGlobal memory on? – user1173240 Jun 11 '15 at 11:53
  • 2
    No, that has the same problem. `StringToHGlobalUni` has within it a call to `AllocHGlobal`. *Every* call to `AllocHGlobal` must have a corresponding call to `FreeHGlobal`, and It is your responsibility to make that call. – David Yaw Jun 11 '15 at 12:03
  • Thank you. I understand. – user1173240 Jun 15 '15 at 03:33
  • If I have a managed string, which I then pass along using `StringToHGlobalUni` to another function, as, `someFunc((LPCTSTR)Marshal::StringtoHGLobalUni(v).ToPointer())`, then does the memory still need to be freed, and if so, in which function? Would the compiler not create a copy of it, and destroy it itself once the function boundary is passed, and it has passed out of the managed scope into unmanaged? Would the called function need to take care of calling `FreeHGlobal`? – user1173240 Jun 24 '15 at 06:25
  • Yes, it still needs to be freed. You can free it in either function, but better would be to pass the managed `String^`. It will *not* be automatically cleaned up when it goes out of scope, because the only thing that has a scope is the *pointer* to the block of memory, not the block of memory itself. – David Yaw Jun 24 '15 at 13:40