My application will be looping for 5000 times. On each iteration, it has to create a string and pass that into other methods for processing. This string length will only be known at the runtime.
So in each iteration, this is what happens.
ptr = malloc process(ptr) free(ptr)
I am wondering doing frequent malloc and free is ok? Will this fragment the memory?
My development environment is GCC and Linux. But I'd be happy to know about the implementation in windows also.
> My application will be looping for 5000 times. On each iteration, it > has to create a string and pass that into other methods for > processing. This string length will only be known at the runtime.
> So in each iteration, this is what happens.
> ptr = malloc > process(ptr) > free(ptr)
> I am wondering doing frequent malloc and free is ok? Will this > fragment the memory?
> My development environment is GCC and Linux. But I'd be happy to know > about the implementation in windows also.
Unlikely. When you create strings and delete strings at random you might fragment the memory, but if you are matching allocations to frees then the system will usually resuse the memory. (If you print out the pointers with %p you'll probably find that you get the same value time after time).
Unless the strings are extremely long then a modern computer isn't going to notice allocating 5000 of them.
> Unless the strings are extremely long then a modern computer isn't > going to notice allocating 5000 of them.
Thanks. My strings are not long. May be 20 characters.
So in general, can malloc fragment the memory? I was expecting the modern implementations will be clever enough to reduce this problem. Isn't that true?
On Wed, 17 Nov 2010 04:00:25 -0800 (PST), Navaneeth <navaneet...@gmail.com>
wrote: >> Unless the strings are extremely long then a modern computer isn't >> going to notice allocating 5000 of them.
> Thanks. My strings are not long. May be 20 characters.
You know, if you have a very short maximum cap for the length, you could just allocate that and reuse the buffer. (You could also by default reuse the buffer and only reallocate a larger one as it becomes necessary.)
That said, the first response was correct in that it's not likely to make much of a difference in this quite simple case. In general though, I would avoid unnecessary repeated allocations and frees in a tight loop.
> So in general, can malloc fragment the memory?
In general, it can indeed. Especially if your processing step here involves allocating space that _isn't_ freed, it can happen in your example too, but probably not to a large extent. (The malloc implementation just needs to be smart enough to reuse the space left by the previous freed buffer, in the common case that it's sufficiently large).
Navaneeth <navaneet...@gmail.com> wrote: > My application will be looping for 5000 times. On each iteration, it > has to create a string and pass that into other methods for > processing. This string length will only be known at the runtime. > So in each iteration, this is what happens. > ptr = malloc > process(ptr) > free(ptr) > I am wondering doing frequent malloc and free is ok? Will this > fragment the memory?
As per MM's reply, not a problem. Nevertheless, I usually do this kind of thing, when I very temporarily need lots of short strings, with a short function that allocates memory from a static array used as a wraparound buffer, something like as follows, #define BUFFSZ 1000 /* any size you like */ void *tempalloc(int nbytes) { static unsigned char buffer[BUFFSZ]; /* buffer */ static int index = 0; /*start at beginning of buffer*/ void *p = NULL; /* returned ptr */ if ( nbytes <=0 || nbytes > BUFFSZ ) goto end_of_job; /* error */ if ( index+nbytes > BUFFSZ ) index=0; /* wrap buffer */ p = (void *)(buffer+index); /* ptr returned to caller */ index += nbytes; /* next ptr past returned nbytes */ end_of_job: return(p); } /* back to caller */ No need to free, or anything. You just have to be logically sure you won't still be using the memory when it's "realloc'ed" after the internal static buffer wraps around. (And the above code doesn't align returned memory on anything.) -- John Forkosh ( mailto: j...@f.com where j=john and f=forkosh )
> Navaneeth <navaneet...@gmail.com> wrote: > > My application will be looping for 5000 times. On each iteration, it > > has to create a string and pass that into other methods for > > processing. This string length will only be known at the runtime. > > So in each iteration, this is what happens. > > ptr = malloc > > process(ptr) > > free(ptr) > > I am wondering doing frequent malloc and free is ok? Will this > > fragment the memory?
> As per MM's reply, not a problem. Nevertheless, I usually do > this kind of thing, when I very temporarily need lots of short > strings, with a short function that allocates memory from a > static array used as a wraparound buffer, something like > as follows,
A variant that will deal with long strings (this is the method described by Mikko Rauhala). The idea is malloc once and reuse the buffer. Only realloc if you have to.
(untested, no error checking)
#define BUFFSZ 20 /* any size you like, 2 will do */ #define MEM_INCREMENT 2 /* unless you have a good reason use 2 */
This has the advantage of portable alignment and it will not fail if a large allocation is requested. It has the disadvantage that it requires the use of the library malloc. You can only use tempalloc safely if you are sure that you do not need the memory from a previous call to tempalloc any more.
> My application will be looping for 5000 times. On each iteration, it > has to create a string and pass that into other methods for > processing. This string length will only be known at the runtime.
> So in each iteration, this is what happens.
> ptr = malloc > process(ptr) > free(ptr)
> I am wondering doing frequent malloc and free is ok? Will this > fragment the memory?
[...]
Depending on what sizes you malloc, and what order you do so, and what other memory allocating/freeing might be going on, the answer is a definite "maybe".
I might suggest a tweak to your method, however.
Keep track of the size you allocated. Then, rather than unconditionally freeing it and allocating a new chunk, check the new size that you need. If the current allocation is at least that large, use the current allocation. Otherwise, free/malloc, and keep track of the new size. Then, after the loop is finished, free the memory once and for all.
And, if you're feeling adventurous, start with a block of memory that "should" be sufficient for "most" scenarios.
> My application will be looping for 5000 times. On each iteration, it > has to create a string and pass that into other methods for > processing. This string length will only be known at the runtime.
> So in each iteration, this is what happens.
> ptr = malloc > process(ptr) > free(ptr)
> I am wondering doing frequent malloc and free is ok? Will this > fragment the memory?
> My development environment is GCC and Linux. But I'd be happy to know > about the implementation in windows also.
Sounds like a region allocator might help you out a bit:
> > Unless the strings are extremely long then a modern computer isn't > > going to notice allocating 5000 of them.
> Thanks. My strings are not long. May be 20 characters.
> So in general, can malloc fragment the memory? I was expecting the > modern implementations will be clever enough to reduce this problem. > Isn't that true?
I suspect that it might be true of the ancient implementations as well.
Section 8.7 of the 1978 edition of The C Programming Language describes a storage allocator system in which the freeing function, merges the freed regions of memory, for the allocating function to use.
> "Navaneeth" <navaneet...@gmail.com> wrote in message > news:8f23500d-4a21-4412-b799-9547e7e5714e@t35g2000yqj.googlegroups.com... >> My application will be looping for 5000 times. On each iteration, it >> has to create a string and pass that into other methods for >> processing. This string length will only be known at the runtime.
>> So in each iteration, this is what happens.
>> ptr = malloc >> process(ptr) >> free(ptr)
>> I am wondering doing frequent malloc and free is ok? Will this >> fragment the memory?
>> My development environment is GCC and Linux. But I'd be happy to know >> about the implementation in windows also.
> Sounds like a region allocator might help you out a bit:
Or, you might be able to do something really simple like:
On Wed, 17 Nov 2010 04:00:25 -0800, Navaneeth wrote: > So in general, can malloc fragment the memory? I was expecting the > modern implementations will be clever enough to reduce this problem. > Isn't that true?
They will try to minimise it, but it isn't always possible.
E.g.:
for (n = n0; n <= n1; n++) { void *p = malloc(n); void *q = malloc(1); ... free(p); }
Each new allocation will be 1 byte too large to fit into the space for the previous allocation. Some of them will fit due to the previous allocation having been oversized, but they can't all fit.
If you really need to prevent fragmentation, you need a relocating allocator, which implies a different interface. With malloc(), any returned pointer remains valid until free()d; the implementation can't just move blocks as it chooses.
>has to create a string and pass that into other methods for >processing. This string length will only be known at the runtime.
>So in each iteration, this is what happens.
>ptr = malloc >process(ptr) >free(ptr)
>I am wondering doing frequent malloc and free is ok? Will this >fragment the memory?
If you only hold on to one string at a time, it is unlikely you will fragment memory much. Each time through the loop, you will go back to the state of everything freed. A "reasonable" allocator will recombine adjacent allocations when both are freed.
For programs like you describe, it might be less time-consuming to keep re-using the single chunk of memory as long as it's big enough, and realloc() it larger when needed.
Here's an example of (rather horribly) fragmenting memory:
You have only 1000TB of memory for string data. You allocate 10,000,000,000,000 strings averaging 100 bytes each (including malloc() bookkeeping overhead) and maybe ranging in size from 50-150 bytes. (Perhaps these are DNA fragments from various species.) This just about fills up the memory. Now free() all but 10,000,000 of them, but which of the strings gets free()d and which gets kept depends somewhat randomly on external data. There is only about 0.001 TB of memory still allocated, but the strings are scattered all over, so good luck trying to allocate 1TB of contiguous memory, even though you've got 1,000 times that in free memory.
Oh, yes, malloc()/free() cannot move allocated memory unless there's a sophisticated garbage collector that can track down all references to memory in use, including in files.
Some allocators try to avoid fragmentation by taking large requests from one pool, and tiny requests from another, perhaps with a whole range of power-of-two-sized blocks. That can be effective, but not in the above case, since all of the strings were roughly the same size.