2013-05-29 1 views
0

Как освободить указатель на пустоту.освобождение указателя пустоты

struct vStruct { 
    void *vPtr; 
    struct vStruct *next; 
}; 

struct vStruct sObj; 
struct vStruct *sObjNew = sObj; 

delete sObjNew->vPtr; -----------> Is this correct way to delete void pointer 
delete sObjNew; 

Показаны ошибки оператора «Удалить», примененная к аннулированию * аргумент того, имеет неопределенное поведение, и, скорее всего, не вызывает деструктор объекта.

+0

Если один из ответов решает вашу проблему, пожалуйста, не забудьте пометить его как принятое, чтобы оно помогло дальнейшим посетителям этого сайта. – Spook

ответ

3

Вы не должны удалить указатель void. delete работает для определенных типов (например, что компилятор знает, какой деструктор должен быть вызван - как указано в сообщении об ошибке).

Если вы хотите сохранить неуказанный тип в своей структуре, вы должны каким-то образом его обернуть.

class DataWrapper 
{ 
public: 
    virtual void * GetData() = 0;    
    virtual ~DataWrapper() 
    { 
    } 
}; 

class MyDataWrapper 
{ 
protected: 
    MyData * data; 

public: 
    MyDataWrapper(MyData * newData) 
    { 
     data = newData; 
    } 

    void * GetData() 
    { 
     return data; 
    } 

    ~MyDataWrapper() 
    { 
     delete data; 
    } 
}; 

struct vStruct 
{ 
    MyDataWrapper * vPtr; 
    struct vStruct *next; 

    ~vStruct() 
    { 
     if (vPtr != null) 
      delete vPtr; 
    } 
}; 

vStruct sObj; 
sObj.vPtr = new MyDataWrapper(new MyData()); 

// When sObj gets deleted, MyDataWrapper is 
// deleted too (thanks to the ~vStruct) and 
// in effect, the allocated data is deleted too. 

Обратите внимание, что это простой пример, его можно написать более эстетично.

9

Вы не указали delete указатель на пустоту. Зачем? Потому что:

«удалить», примененная к void* аргумент имеет неопределенное поведение, и, скорее всего, не вызывает деструктор объекта.

Как ваш компилятор узнает, какой тип имеет объект pointee? И поэтому какой деструктор позвонить? (Хотя он, вероятно, может определить, сколько памяти освободится, в зависимости от механизма распределения.)

Не храните void* используйте вместо этого «настоящий» тип указателя. Если вам нужно «скрыть» истинный тип, подумайте об использовании полиморфизма вместо устаревших методов C.

3

Как был vPtr?

  • Если это указывает на то, что структура не принадлежит, вы не должны ее уничтожать.
  • Если он указывает на данные, созданные с помощью malloc, вы должны позвонить free.
  • Если это указывает на данные, созданные с помощью new, перед тем, как позвонить delete, вам нужно будет применить его к правильному (или совместимому) типу, чтобы вызывать правильный деструктор.

Обратите внимание, что ваш пример кода не компилируется, но предполагает, что vPtr не инициализируется вообще. Вы должны инициализировать vPtr во всех созданных вами экземплярах vStruct. Попытка освободить uninitialized vPtr имела бы неопределенные последствия, но, скорее всего, сбой.

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

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