Pinecone
Pinecone

Reputation: 421

Swift UnsafeMutablePointer memory allocation and deallocation in a function

I am programming using Swift 2.2 on Mac OS X 10.11. I have a function that looks like this:

func aFunction(direntPointer: UnsafePointer<dirent>, usingBuffer bufPointer: UnsafeMutablePointer<CChar>) {
    let tempBuf = UnsafeMutablePointer<CChar>.alloc(2048)

    ... [put the filename from the dirent into tempBuf and do some processing]

    // Transfer the data in the temporary buffer into the provided buffer
    bufPointer.moveAssignFrom(tempBuf, count: 2048)

    // Seems necessary, but destroys the data in bufPointer as well
    tempBuf.dealloc(2048)

    return
}

The bufPointer is set up in a calling function as:

let bufPointer = UnsafeMutablePointer<CChar>.alloc(2048)

Upon return to the calling routine, bufPointer does not contain valid data. However, if I remove the tempBuf.dealloc() method call, then tempBuf contains valid memory and the routine works as expected. According to the literature, the moveAssignFrom() method destroys the source memory more efficiently that doing a separate move() and then destroy().

My question is whether the dealloc() method call is necessary to avoid a memory leak or if it does not matter because it is being created on the stack and is just being destroyed upon return? The Apple literature says that allocated memory needs to be deallocated, but I cannot return valid data if it is deallocated.

Perhaps there is a better way to do this? The purpose of the function call is to consolidate the code to avoid repeating it because it is being called from multiple places, and to process the filename that is retrieved from the dirent.

Thank you

Upvotes: 1

Views: 1313

Answers (1)

Pinecone
Pinecone

Reputation: 421

After a lot of searching, the answer appears to be that since, according to Apple, the memory is not managed, when the temporary buffer is "moved" into the provided buffer, the compiler feels justified in simply pointing the provided buffer to the area of memory pointed to by the temporary buffer, so that when the temporary buffer is destroyed and deallocated, the provided buffer loses its memory. No matter what I tried, I could not get the provided buffer to have a copied buffer, since the compiler was just ignoring that and assigning the pointer.

The obvious solution is to wrap the provided buffer around an Unmanaged NSData object before the call, then retain and release outside of the function. But the better solution is not to use a temporary buffer inside the function at all, and just use the provided buffer, then deallocate it in the calling routine.

Upvotes: 1

Related Questions