Почему я могу сделать «удалить p;», а не «удалить (p + 1);»? Почему для удаления требуется lvalue? - PullRequest
4 голосов
/ 17 апреля 2010

На этой странице написано, что

Одной из причин является то, что операнд удаление не обязательно должно быть lvalue. Рассмотрим:

delete p+1; 
delete f(x); 

Здесь реализация delete не имеет указатель, которому можно присвоить ноль.

Добавление числа к указателю смещает его вперед в памяти на такое количество единиц sizeof(*p).

Итак, в чем разница между delete p и delete p+1 и почему указатель 0 будет проблемой только с delete p+1?

Ответы [ 4 ]

8 голосов
/ 17 апреля 2010

Вы не можете сделать p + 1 = 0. По той же причине, если вы сделаете delete p + 1, тогда delete не сможет обнулить свой операнд (p + 1), о чем вопрос в FAQ Страуструпа.

Вероятность того, что вы когда-либо напишите delete p+1 в программе, довольно мала, но это не относится к делу ...

5 голосов
/ 17 апреля 2010

p и p + 1 указывают на разные места, как вы правильно сказали sizeof(*p) единицы. Вы не можете удалить то, что не было выделено, но, например:

A* p = new A();
p++;
delete p-1;

удалит исходное распределение. Удаление p + 1, когда p + 1 не было выделено изначально, не определено; Глеб всплывает с:

*** glibc detected *** free(): invalid pointer: 0x0804b009 ***

Реализация не может обнулять p + 1, потому что p + 1 не является переменной для изменения. В этом пункте говорилось, что

delete p;

можно перевести на

free(p);
p = 0;

Это не имеет смысла с p + 1

1 голос
/ 29 сентября 2012

На самом деле, вы можете delete значение. Ничто в спецификации (n3242) не исключает этого. На практике это не дает ошибок .

Кстати, если в статье написано

операнд удаления не обязательно должен быть lvalue

это означает, что может быть или не быть lvalue. Это не говорит, что операнд не может быть lvalue.

0 голосов
/ 17 апреля 2010

Причина в том, что ни одно из этих значений не является lvalue, поэтому установить их в NULL (или любое другое значение) просто невозможно.

...