freeing memory

I have allocated memory for a string-type variable inside a C dll using new(char[n]). This dll is called from a VB application. I am returning this string to the calling VB function. Is the memory automatically freed or do I have to do it? How should I do it? I cannot free the variable inside the dll as I cannot return it in that case.
arvind_csAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

abancroftCommented:
The ususal way to handle this problem is to have the calling function (VB) declare the string buffer & size it. It then passes the LPSTR pointer & buffer length to your function. That way the function can return a success code.

e.g.
In VB:
  Dim strParam as String(255)
  DLLFunction(strParam, 255)

C declaration:
 void DLLFunction(LPSTR szStr, int nStrLen);

Did you mean a C++ DLL? If this really is a C DLL, you can't be using 'operator new' - that is a C++ only feature.
0
BigOneCommented:
The module that allocates the memory should also free the memory.  If you can't pass a char * to an allocated buffer, consider other alternatives.  The memory is NOT automatically freed up so you definatley need to deal with it
0
WynCommented:
>>Is the memory automatically freed or do I have to do it?
no.
you should free it using delete

>>I cannot free the variable inside the dll as I cannot return it in that case.
why?
how you return the string,you can copy it then you can delete in the dll when the dll is released.
or if it's in a class,you can delete it int the destruction.
0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

WynCommented:
To bigone:
Why you submit as an answer?
0
BigOneCommented:
Bad Timing.  I missed Abancroft's comment.  His should answer the question
0
abancroftCommented:
Looks like we posted at the same time - I must've got there first by a few seconds.

The competition here is pretty intense...
0
arvind_csAuthor Commented:
No. Let me illustrate my question with an example:

'VB Application:
Dim sRet as string

sRet = CDllFuntion()
'------------------
//C Dll
char* __stdcall CDllFunction(void)
{
 char *RetString=NULL;
 int iIter;
 RetString = new(char[100]);
 
 for(iIter=0;iIter<99;iIter++)
 RetString[iIter]= 'z';

/*
 delete(RetString);
 This is not possible  as I cannot return after de-allocating memory
*/

 return(RetString);

 /*
 delete(RetString);
 This won't work as this line will not be executed since it is after return statement
*/

}

Would memory be freed if I use LoadLibrary and FreeLibrary before and after calling CDllFunction in VB?
How else can I do it?



0
abancroftCommented:
You have 2 problems here:
1. As you noted, you can't explicity free memory in VB so it leaks.
2. You return a char* - but this is not the same as a VB string.

You could try using SysAllocString() and returning a BSTR (which is VB compatible I think). That way the VB string may correctly delete it.
0
arvind_csAuthor Commented:
No, I have tried that but it doesn't help. Any other ideas, anybody?
0
arvind_csAuthor Commented:
No, I have tried that but it doesn't help. Any other ideas, anybody?
0
abancroftCommented:
I've just found an MSDN article on this. Basically they allocate & return a BSTR. Here's their example:

   #include <windows.h>
   #include <ole2.h>

   #ifdef _WIN32
     #define CCONV _stdcall
     #define NOMANGLE
   #else
     #define CCONV FAR PASCAL _export
     #define NOMANGLE EXTERN_C
     #include <stdlib.h>
     #include <compobj.h>
     #include <dispatch.h>
     #include <variant.h>
     #include <olenls.h>
      #endif

   NOMANGLE BSTR CCONV UpperCaseByRef(BSTR *pbstrOriginal)
   {
       BSTR bstrUpperCase;
       int i;
       int cbOriginalLen;
       LPSTR strSrcByRef, strDst;

       //This is code to allocate a BSTR that points to an
       //ANSI string for 16 or 32 bit.
       #if !defined(_WIN32)
          // 16 bit uses ANSI strings to char = byte
          cbOriginalLen = SysStringLen(*pbstrOriginal);
       #else
          //32 bit uses UNICODE strings char = 2 * byte
            //but Visual Basic passed an ANSI string.
              cbOriginalLen = SysStringByteLen(*pbstrOriginal);
       #endif

       bstrUpperCase = SysAllocStringLen(NULL, cbOriginalLen);

       strSrcByRef = (LPSTR)*pbstrOriginal;
       strDst = (LPSTR)bstrUpperCase;

       //Using runtime function for ANSI strings
       for(i=0; i<=cbOriginalLen; i++)
           *strDst++ = toupper(*strSrcByRef++);

       //Placing ANSI string in for return to Visual Basic
       SysReAllocString (pbstrOriginal, (BSTR)"Good Bye");

       return bstrUpperCase;
   }

0
abancroftCommented:
And....

NOMANGLE BSTR CCONV UpperCaseByVal(BSTR bstrOriginal)
   {
       BSTR bstrUpperCase;
       int i;
       int cbOriginalLen;
       LPSTR strSrcByVal, strDst;

       // This is code to allocate a BSTR that points to an
       // ANSI string for 16 or 32 bit.
       #if !defined(_WIN32)
          // 16-bit uses ANSI strings to char = byte
          cbOriginalLen = SysStringLen(bstrOriginal);
       #else
          // 32-bit uses UNICODE strings char = 2 * byte
          // but Visual Basic passed an ANSI string.
             cbOriginalLen = SysStringByteLen(bstrOriginal);
       #endif

       bstrUpperCase = SysAllocStringLen(NULL, cbOriginalLen);

       strSrcByVal = (LPSTR)bstrOriginal;
       strDst = (LPSTR)bstrUpperCase;

    // Using run-time function for ANSI strings
    for(i=0; i<=cbOriginalLen; i++)
        *strDst++ = toupper(*strSrcByVal++);
    // Placing ANSI string in for return to Visual Basic.
    SysReAllocString (&bstrOriginal, (BSTR)"Good Bye");

    return bstrUpperCase;
   }
0
abancroftCommented:
The VB code:

#If Win32 Then

       Private Declare Function UpperCaseByRef Lib "vb4dll32.dll" (Str _
           As String) As String
       Private Declare Function UpperCaseByVal Lib "vb4dll32.dll" _
           (ByVal Str As String) As String

   #Else

       Private Declare Function UpperCaseByRef Lib "vb4dll16.dll" (Str _
           As String) As String
       Private Declare Function UpperCaseByVal Lib "vb4dll16.dll" _
           (ByVal Str As String) As String

   #End If


   Private Sub StringTest ()

      Dim Str As String, NewStr As String

      Str = "Hello World!"
      MsgBox "In VB, Before: " & Str
      NewStr = UpperCaseByRef(Str)
      MsgBox "In VB, After: " & Str
      MsgBox "In VB, CapsStr: " & NewStr

      Str = "Hello World!"
      MsgBox "In VB, Before: " & Str
      NewStr = UpperCaseByVal(Str)
      MsgBox "In VB, After: " & Str
      MsgBox "In VB, CapsStr: " & NewStr

   End Sub
0
arvind_csAuthor Commented:
Thanks abancroft. The code works fine.
0
abancroftCommented:
Great - so you'll accept this answer?
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
arvind_csAuthor Commented:
Yes.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.