Solved

malloc'ing something in a function, and releasing it outside the function?

Posted on 1998-12-25
11
221 Views
Last Modified: 2010-08-05
Hi,
  i have a problem/questions about releasing memory which has been allocated inside a function.

it looks like this:

char *a_function(void)
{
  char *buffer;

  buffer = (char *)malloc(10000);
  return buffer;
}

is there a better way then using "free(buffer)" outside the
function (sometimes after the data in buffer is not needed anymore)? this is not really a problem - but it is easy to
forget to "free(buffer)" which would lower the amount of
memory alot :(
0
Comment
Question by:SPooK
[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
  • 2
  • 2
  • +3
11 Comments
 
LVL 1

Expert Comment

by:TheMadManiac
ID: 1255419
Not that i now of. C needs memory allocations to be explicitly deallocated. What you can do to test if you deallocate them all, is to write a function that deallocates the memory allocated in a_function().

then in the a_function you write something into a logfile, and in the deallocation routine you also write something in a log file. Then at the end of a program run, you compare how many allocations and  deallocations you have, and if they don't match, you've forgotten it somewhere. In the final release of the program you can just comment out the logwrite's and that's all.

hope this helps,

 Floris
0
 
LVL 10

Expert Comment

by:rbr
ID: 1255420
No in standard C there will be no other way. You have to free the memory with the pointer returned by the malloc ( or any other alloc) routine. Can you pls give more info what you want to do exactly. Maybe there will be another way for programming it.
0
 

Author Comment

by:SPooK
ID: 1255421
Hi rbr,
  i rejected your answer to see if i'd get any other comments, also below is the original function which i have this problem with.
if there are not any more useful answers please post an emtpy answer and i'll give you the points.

  what this function does is it just convert an integer number to a zero terminated string and return the address of the string:

char *int2str(int number)
{
      char *temp, x;
      int counter=0, i;

      temp =(char *)malloc(11);  // 11 should be enough for a 32 bit number

      if (!number)
      {
            temp[0]='0';
            counter++;
      } else
      {
      while (number)
      {
            x = number % 10;
            number /= 10;
            temp[counter] = x + '0';
            counter++;
      }
      }
      temp[counter] = 0;

      strrev(temp);
      return temp;
}

  maybe what i should add is a realloc(temp, strlen(temp))? this would atleast keep the lost memory as small as possible if someone would forget to free(temp).

this 11 lost bytes are not much, true, but only if the function is called once, in the program
i actully wrote the function for it gets called about 20000 upto 90000 times each time it is executed.

0
Independent Software Vendors: 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 10

Expert Comment

by:rbr
ID: 1255422
The problem is if you use realloc you only get one correct pointer if you call your function twice.

char *buffer1,*buffer2;

buffer1=int2str(10);
buffer2=int2str(20);
will only workif you use alloc everytime and you don`t realloc the memory in your function since after the second call your first pointer isn`t valid any more. Why don`t you pass the buffer where to store the information to the function.
0
 
LVL 2

Accepted Solution

by:
obg earned 100 total points
ID: 1255423
If you use the function above, the caller has to "free" the buffer. Another solution is to provide the function with a buffer provided by the caller. - Make it int (or void) int2str(char *str, int number). Then you can let the caller free the buffer or use it again, or whatever.

I think that rbr has missunderstood something here, regarding the last comment (or maybe I have)... Your (SPooK) thoughts are correct. You can realloc the buffer as you said, to minimize memory leaks. Since you allocate a new buffer each time, there will be no conflicts.
0
 
LVL 11

Expert Comment

by:alexo
ID: 1255424
There is another possibility:  Use a static buffer (like strtok() uses).  Oh, there are certain problems with this approach (you cannot have two outstanding requests) but there will be no memory leaks.

If you don't like explicit free() calls, you can request the user to call a cleanup() function that will do the free().
0
 
LVL 2

Expert Comment

by:obg
ID: 1255425
A cleanup function is a possibility, but then he would have to keep track on every allocated block in a linked list (for example). He would also have to find an opportunity to call the cleanup, and then there's not much difference to calling free each time...

A static buffer might be useful, but you'd have to avoid misstakes like this (as you say):
buffer1=int2str(10);
buffer2=int2str(20);
in which case buffer1 and buffer2 would point to the same (static) buffer, which will hold the string "20". In this case you'd have to copy the result to your own buffer after the first call...

I still vote for my idea with a caller provided buffer. It is more flexible.
0
 
LVL 11

Expert Comment

by:alexo
ID: 1255426
>> I still vote for my idea with a caller provided buffer. It is more flexible.
It is a good solution but care must be taken to deal with buffer overflows, etc.
0
 
LVL 3

Expert Comment

by:NullTerminator
ID: 1255427
Follow obq's advise, but you can still return char*
char *int2str( char* in, int val) {
// do the convrsion
return in;
}

Then you can still do direct assignments
char numstr[20] = {'\0'};
strcat("some number string %s", int2str(numstr, 999);
0
 

Author Comment

by:SPooK
ID: 1255428
providing the function with a buffer created by the user is probably the best method, thanks for all your comments and answers! :o)

0
 
LVL 10

Expert Comment

by:rbr
ID: 1255429
Why do you accept obg answer and reject my answer and my comment. Obg didn`t tell you anything more than I.
0

Featured Post

Industry Leaders: 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!

Question has a verified solution.

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

Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.

734 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