views:

289

answers:

1

The legacy database that I'm interfacing with uses a data buffer to pass rows to applications. To handle this in C#, I wrote a class that provides methods for reading and writing different types in the buffer. Each data file uses one data buffer, but the buffer has to be resized for certain operations. To do this, I added an Allocate method:

public void Allocate(int bytes) {
    if (handle != IntPtr.Zero) { // memory has already been allocated
        Marshal.FreeHGlobal(handle);
    }
    handle = Marshal.AllocHGlobal(bytes);
}

That was before I noticed ReAllocHGlobal, however. Now I'm wondering if I should do this:

public void Allocate(int bytes) {
    if (handle != IntPtr.Zero) { // memory has already been allocated
        handle = Marshal.ReAllocHGlobal(handle, (IntPtr)bytes);
    } else { // this is a brand new data buffer
        handle = Marshal.AllocHGlobal(bytes);
    }
}

I think the first method looks cleaner, but which is the best to use? My first thought was that ReAllocHGlobal makes the most sense (since it's specifically for resizing an existing block of memory), but I'm not 100% certain.

+3  A: 

If you don't need to retain the information in the buffer, freeing and allocating a new buffer is the better option. If ReAlloc needs to allocate the buffer in a different location, it will copy the existing contents.

On the other hand, if you want to retain the contents of the buffer and extend (or shrink) it, ReAlloc is the simpler approach.

Zooba
I think Free/Alloc is a simpler pattern to use then ReAlloc. I've not had any experience with these, but I stay away from CoTaskMemReAlloc() because of past bad experiences. Though I forget what they were now. If you find yourself allocing and freeing a lot you may consider using a custom arena.
jeffamaphone
Thank you! The buffer does need to be cleared before each operation. Sorry for not stating that in my original question.
David Brown
@jeffamaphone The problem being that Free/Alloc is actually Alloc/Free if you want to retain the contents, which also guarantees a copy, whereas ReAlloc will only copy if it actually has to relocate the memory.
Zooba