2013-05-29 1 views
-4

что не так с кодом. Что это должно быть. Так как это ошибка. Оператор «delete», применяемый к аргументу void *.удаление указателя пустоты с использованием оператора удаления

int i; 
void *ptr = &i; 

delete ptr; 
+0

http://stackoverflow.com/questions/941832/is-it-safe-to-delete-a-void-pointer – spiritwolfform

+0

'throw' обычно используется в контексте времени выполнения. Вы говорите о компиляторе, сообщающем об ошибке с вашим кодом. –

+0

@PeterWood: приведенный выше код, вероятно, компилируется отлично ... –

ответ

0

Ваш код не будет работать, потому что вы пытаетесь удалить что-то, что не было динамически распределено.
В любом случае удаление указателей пустоты не определено, см. this Q&A для получения дополнительной информации

+0

ссылка, о которой вы упомянули, не отвечает на мой вопрос. int * i = new int; void * ptr = i; удалить ptr; Это нормально? – Anand

+0

@Anand Он очень хорошо отвечает на ваш вопрос. Посмотрите на второй ответ. – Gorpik

1

Очень озорной код действительно;

  1. Вы не берете адрес i; используйте вместо этого void* ptr = &i . Вы являетесь компилятором, очень мягким, чтобы испускать свой код.
  2. Вы удаляетесь из стека. Нехорошо. Вы можете только delete вещи вы new эд
  3. компилятор не знает, сколько памяти, чтобы удалить, если вы проход void*, как теряются все данные sizeof.
2

Вы должны удалить только те предметы, которые были выделены новым.

+0

Абсолютно верно, но это не является причиной сообщения об ошибке. – Gorpik

+0

Да, поскольку вы не можете выделить указатель типа void с новым, вы также не можете его удалить. – QI3it

+0

Вы можете. Просто измените этот код на 'int * i = new int; void * ptr = i; '. 'ptr' теперь указывает на объект, созданный с помощью' new', но вы не можете удалить его из-за его типа. – Gorpik

7

что не так с кодом.

Все, кроме int i;

Вторая строка пытается преобразовать целое число в указатель. В особых случаях вы можете заставить это компилятор с reinterpret_cast; но программа будет вести себя корректно, если целое число каким-то образом содержит допустимое значение указателя. (UPDATE: вопрос теперь отредактирован, чтобы вместо этого взять адрес i, поэтому эта строка больше не является ошибкой).

Третья строка пытается удалить недопустимую память с использованием недопустимого типа указателя.

Что это должно быть.

Что-то еще. Не зная, что вы хотите сделать, невозможно сказать. Может быть, вы хотите:

int i; 
void * ptr = &i; // Points to `i`, losing type information. 

delete оператора, примененного к void* аргумента.

Это всегда неправильно. Вы должны только delete объект, который вы ранее выделили new; и указатель должен быть верным.

(или базового класса, если это тип класса с виртуальным деструктора)

Так следующее будет правильным; но бессмысленно, если у вас есть веские основания для динамического распределения:

int * ptr = new int; 
delete ptr; 

И, конечно, если вы пишете код, который должен быть устойчивым к утечкам памяти и ошибкам во время выполнения, вы должны управлять всей динамической памятью с помощью RAII типов таких как контейнеры и интеллектуальные указатели. Так что, если вам нужно динамический объект, вы должны сделать:

std::unique_ptr<int> ptr(new int); 

, если вы хотите, чтобы удалить его в конце текущей области или переместить его в другую область; или

auto ptr = std::make_shared<int>(); 

Если вы хотите разделить собственность между несколькими областями. В любом случае указатели будут удалять объект автоматически, как только вы закончите с ним.

+0

int * i = new int; void * ptr = i; удалить ptr; Это нормально ? – Anand

+1

@Anand: Нет, потому что вы должны использовать 'int *' для удаления 'int'. Без правильной информации о типе 'delete' дает неопределенное поведение. –

+0

то в этом случае, как удалить ptr? – Anand

 Смежные вопросы

  • Нет связанных вопросов^_^