Deepak Sharma
Deepak Sharma

Reputation: 6581

Swift deallocate vs free usage

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

Answers (1)

Ky -
Ky -

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.

Edit 2024-03-09

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

Related Questions