Reputation: 6581
I am allocating bytes using the following call in Swift 3:
let wordSize = 2
let numbytes = 1024*wordsize
var ptr = UnsafeMutableRawPointer.allocate(bytes: numbytes, alignedTo: wordSize)
Question is whether it is correct to deallocate the memory, are both these calls one and the same, or I should be using one over the other?
free(ptr) // opt 1
ptr.deallocate(bytes: numbytes, alignedTo: wordSize) //opt 2
Upvotes: 4
Views: 2092
Reputation: 32143
Swift 4 changed this signature to deallocate()
, making it much easier to decide when compared to free(_:)
.
As Hamish pointed out, deallocate
is the preferred way to deallocate unsafe pointers in Swift, a fact which is reinforced by the API designers placing this function on the type and documenting it, whereas free(_:)
is global-scope (rarely appropriate in Swift) and undocumented.
I should point out that it goes a little bit deeper than that.
.deallocate()
is a Swift language function, whereas
free(_:)
is a C/UNIX/POSIX function.
This means that the Swift language maintainers can improve .deallocate()
if needed (for example, making a throwing version in case some problem occurred, or improving performance in memory-constrained environments, having specialized variants for certain types of pointers, etc.),
whereas free(_:)
is an OS-level call with some restrictions on how it can be implemented.
On that note, free(_:)
actually is documented, but just like other UNIX/POSIX calls, that documentation isn't included in Swift docs. The free(_:)
documentation is in UNIX documentation (defined in stdlib.h
), and includes the following:
NAME
free - free allocated memory
SYNOPSIS
#include <stdlib.h> void free(void *ptr);
DESCRIPTION
[CX] ⌦ The functionality described on this reference page is aligned with the ISO C standard. Any conflict between the requirements described here and the ISO C standard is unintentional. This volume of POSIX.1-2017 defers to the ISO C standard. ⌫
The free() function shall cause the space pointed to by ptr to be deallocated; that is, made available for further allocation. If ptr is a null pointer, no action shall occur. Otherwise, if the argument does not match a pointer earlier returned by a function in POSIX.1-2017 that allocates memory as if by malloc(), or if the space has been deallocated by a call to free() or realloc(), the behavior is undefined.
Any use of a pointer that refers to freed space results in undefined behavior.
RETURN VALUE
The free() function shall not return a value.
ERRORS
No errors are defined.
So you see there's a lot of specific restrictions on what free(_:)
can do, meaning you can call it in Swift because Swift cn call any low-level function, but its specific requirements mean that Swift's version .deallocate()
is more likely to be the correct choice for use in Swift
Upvotes: 5