Solved

C++-DLL and Delphi 3

Posted on 1998-11-09
9
495 Views
Last Modified: 2008-02-01
Hello,

I've written a DLL in Borland C++ 5.0.  One of the functions is a simple
concatenation function :

char* __stdcall _export StringTest(char* Str1, char* Str2)
{
   char* tmp;

   int l1 = strlen(Str1);
   int l2 = strlen(Str2);

   tmp = (char*) malloc(l1+l2+1);
   strcpy(tmp, Str1);
   strcat(tmp,Str2);
   return tmp;
}

This function works fine, but it has a memory leak : the memory
allocated for tmp is not released.

This function is called from a Delphi 3 application.  Can anyone tell me
how I can release the allocated memory, prefarably from the Delphi
application ?
I've tried freeing the memory just before the return instruction, but it
doesn't work.

Thanks in advance,

Johan

0
Comment
Question by:ppr
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
  • 2
  • +1
9 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 1177318
No way. You cannot release memory in a Delphi app that was allocated by a C++ DLL - they use different heaps for this. The only reliable way is to pass in a buffer allocated by the application, e.g.


char* export WINAPI StringTest(char* Str1, char* Str2, char *res)
{
   char* tmp
   strcpy(res, Str1);
   strcat(res,Str2);
   return res;
}

(NOTE the WINAPI modifier!)
0
 
LVL 22

Expert Comment

by:nietod
ID: 1177319
Even if were possible (which it pretty much isn't ), these sort of designs where a procedure allocates memory for a return value and expects the caller to delete it, are notoriously dangerious.  You would ussually get a memory leak anyways because the calling code would probably forget to do the delete anyways, at least in some cases.
0
 

Author Comment

by:ppr
ID: 1177320
Thanks to AndersWP I was able to solve it the way I like it.  In the DLL, I use the GlobalAlloc API function and in the application I use the GlobalFree API.

But thank you for your reaction.

Johan
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Accepted Solution

by:
TheGrinch earned 200 total points
ID: 1177321
I had a similar problem, and couldn't depend on the user of the function doing the "free" for me. So I did something like this...

char* export WINAPI StrTest(char* Str1, char* Str2, char *res)
{
  enum  { nstring = 100, stringl = 2000 };
  static  int  n = -1;
  static  char cbuf[nstring][stringl] = { '\0' };
          char *tmp = cbuf[n=(n+1)%nstring];

  strcpy(tmp, Str1);
  strcat(tmp, Str2);
  return tmp;
}

This function uses a set of 'nstring' "wraparound buffers" of length 'stringl' to hold the return values. After 'nstring' calls, it re-uses an old buffer.

This approach imposes two limitations: The maximum length of the result can't exceed 'stringl' and the maximum number of outstanding return values can't exceed 'nstring'. Depending on how your function is used, this might be a good solution.

You can change 'nstring' and 'stringl' to large values, but they are now on the stack. To make them VERY large, use...

  static char cbuf = (char*)calloc ( nstring, stringl );

After all, it's only virtual memory...

0
 
LVL 22

Expert Comment

by:nietod
ID: 1177322
>>Depending on how your function is used, this might be a
>> good solution.
This could never be a good solution.  For the few cases where you might be able to argure that it is safe, you could easily find better solutions.

If you need powerful string manipulation, use a string class.  It is far safer and far more powerful.

Besides, ppr already has a solution.  ready the question history.
0
 
LVL 1

Expert Comment

by:TheGrinch
ID: 1177323
nietod:

The approach I gave both solves the leakage problem, and allows clients of the DLL to continue to use the function WITHOUT BEING MODIFIED. That was the problem I had (an inability to modify the clients of the DLL).

Incidentally, I agree that there are limitations with my approach, which I clearly stated.

The approach chosen by ppr doesn't do this, nor does the use of a string class do this. Only my approach does this. But maybe this wasn't the problem. ppr wasn't clear whether the clients of the DLL could be changed. I assumed they couldn't. That is a fairly common problem when changing DLLs that are widely used.

I fully agree that a string class is the preferred approach, but your comment that "This could never be a good solution" is not only dead wrong, it reflects a "better than thou" attitude. I'm not taking any offense, but do suggest that you moderate your attitude just a bit :-)
0
 
LVL 1

Expert Comment

by:TheGrinch
ID: 1177324
nietod:

The approach I gave both solves the leakage problem, and allows clients of the DLL to continue to use the function WITHOUT BEING MODIFIED. That was the problem I had (an inability to modify the clients of the DLL).

Incidentally, I agree that there are limitations with my approach, which I clearly stated.

The approach chosen by ppr doesn't do this, nor does the use of a string class do this. Only my approach does this. But maybe this wasn't the problem. ppr wasn't clear whether the clients of the DLL could be changed. I assumed they couldn't. That is a fairly common problem when changing DLLs that are widely used.

I fully agree that a string class is the preferred approach, but your comment that "This could never be a good solution" is not only dead wrong, it reflects a "better than thou" attitude. I'm not taking any offense, but do suggest that you moderate your attitude just a bit :-)
0
 
LVL 22

Expert Comment

by:nietod
ID: 1177325
My thought was that you should never purposefuly write code like that.  If you are backed into it from another programmer's mistake then I guess I might be okay to. . . No it still wouldn't be okay, find the programmer, kill him, steel his code and fix it.  That would be acceptible  : - )
0
 

Author Comment

by:ppr
ID: 1177326
It's not exactly what I was looking for, but I think it will be usefull in the future.
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

756 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question