Por que posso fazer “excluir p;”, mas não “excluir (p+1);”? Por que o exclusão requer um LValue?
-
27-09-2019 - |
Pergunta
Sobre esta página, está escrito que
Uma razão é que o operando de exclusão não precisa ser um LValue. Considerar:
delete p+1;
delete f(x);
Aqui, a implementação do Exclete não possui um ponteiro ao qual ele pode atribuir zero.
Adicionar um número a um ponteiro muda para a frente na memória por muitos números de sizeof(*p)
unidades.
Então, qual é a diferença entre delete p
e delete p+1
, e por que fazer o ponteiro 0
apenas ser um problema com delete p+1
?
Solução
Você não pode fazer p + 1 = 0
. Pelo mesmo motivo, se você delete p + 1
Em seguida, o Delete não pode zerar seu operando (P+1), que é a questão das perguntas frequentes da Stroustrup.
A probabilidade de você escrever delete p+1
Em um programa, é bastante baixo, mas isso é além do ponto ...
Outras dicas
P e P+1 apontam para lugares diferentes, como você disse com razão sizeof(*p)
unidades separadas. Você não pode excluir algo que não foi alocado, mas por exemplo:
A* p = new A();
p++;
delete p-1;
excluiria a alocação original. Excluir p+1 quando p+1 não foi alocado originalmente originalmente é indefinido; Glib sai com:
*** glibc detected *** free(): invalid pointer: 0x0804b009 ***
A implementação não pode zero P+1 porque P+1 não é uma variável para modificar. O parágrafo estava dizendo que
delete p;
poderia ser traduzido para
free(p);
p = 0;
Isso não faz sentido com p+1
Na verdade, você posso delete
um rvalue. Nada na especificação (N3242) o impede. Na prática, isso não dá erro.
Btw se o artigo disser
operando de delete não precisa ser um lvalue
Isso significa que pode ou não ser um LValue. Não diz que o operando não pode ser um LValue.
O motivo é que nenhum desses são LValues, portanto, configurá -los como nulos (ou qualquer outro valor) simplesmente não é possível.