D é uma linguagem de programação de sistema e, portanto, permite o gerenciamento manual da memória. Entretanto, o gerenciamento manual de memória está sujeito a erros de segurança de memória e, portanto, o D usa um coletor de lixo por padrão para gerenciar a alocação de memória.
D fornece tipos de ponteiro T*
como em C:
int a; // a declarado na pilha
int* b = &a; // b contém o endereço de a
auto c = &a; // c é int* e contém o endereço de a
Um novo bloco de memória no heap é alocado usando uma expressão
expressão new T
,
que retorna um ponteiro para a memória gerenciada (quando T é um tipo de valor):
int* a = new int;
Quando a memória referenciada por a
não for referenciada em nenhum lugar
por meio de qualquer variável no programa, o próximo ciclo de coleta de lixo
liberará sua memória. Por padrão, o coletor de lixo só pode ser
executado ao alocar memória com o GC - por exemplo, ao utilizar
a expressão new
.
GC.collect
(a partir de
core.memory
)
GC.disable
(e reativadas com GC.enable
)
As violações de segurança de memória podem:
Para evitar isso, D tem um subconjunto para segurança de memória.
O D tem três níveis de segurança diferentes para as funções: @system
, @trusted
e @safe
.
A menos que especificado de outra forma, o padrão é @system
, que não verifica a segurança da memória.
O @safe
impõe um subconjunto de D que impede a ocorrência de bugs de memória por design.
O código @safe
só pode chamar outras funções @safe
ou @trusted
.
Além disso, a aritmética explícita de ponteiros é proibida no código @safe
:
void main() @safe {
int a = 5;
int* p = &a;
int* c = p + 5; // erro
}
As funções @trusted
são funções verificadas manualmente, que devem ter
uma interface segura para a memória.
Internamente, elas podem executar operações @system
.
Elas permitem uma ponte entre o SafeD e o acesso de baixo nível subjacente.