Solved

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

Posted on 1998-12-25
11
183 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
  • 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
 
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
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
logging Access violation 6 18
memory leak detection 9 51
stack 22 155
C language IDE – Compilers installation 14 58
Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.

707 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

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now