Освобождение указателя от другой функции - PullRequest
1 голос
/ 28 марта 2011

С учетом кода:

#include<iostream>
using namespace std;

class String
{
      char *pstr;
      unsigned size;
      public:
             String(){ pstr=0;size=0;}
             String(const char *);
             void show(){ cout << pstr << endl ; }
             ~String () { cout << "In Dtor" << endl; delete [] pstr; }

};

String::String(const char * cptr)
{
    size = strlen (cptr) + 1;
    cout << "String is - " << cptr << " - of size " << size - 1 << endl ;
    pstr = new char [ size ] ;
    for ( int i = 0 ; i < size ; i++)
        pstr[ i ] = cptr [ i ];

}



int main()
{
    String s("Hello World");
    s.show();
    s.~String();
}

Выход:

    String is - Hello World - of size 11
    Hello World
    In Dtor
----Debug Assertion Failure----
    In Dtor

Почему Деструктор снова вызывается? Когда я вызвал деструктор?

А что такое ошибка утверждения?

Также этот код действителен?

char * ptr=0;    

 void fun()
 {
      const char * p = "Hello World";
      int size = strlen(p )+ 1;
      cout << size << endl;
      ptr = (char *)malloc(size);
      for ( int i = 0 ; i < size ; i++)
      ptr[ i ] = p [ i ];
      cout << p << endl << ptr << endl ;
 }

int main()
{
    fun();   
    free (ptr); --> Note
}

Можно ли освободить указатель от другой функции? Это главное, что я пытаюсь понять здесь.

Ответы [ 2 ]

10 голосов
/ 28 марта 2011

Вы не должны вызывать деструктор вручную - он вызывается, когда s выходит из области видимости в конце '}'

Ошибка подтверждения означает, что что-то называется assert(somecondition), а какое-то условие было ложным.Это метод, используемый для проверки ваших предположений - если ваш код зависит от того, что какое-то конкретное условие является истинным, и это условие действительно должно быть истинным, если у вас нет ошибки, тогда вы вставляете утверждение.

Затем вы можете выбрать компиляцию с включенными утверждениями - это означает, что вы получите такую ​​ошибку, если ваше предположение было неверным.Для сборки выпуска вы часто отключаете утверждения - для оператора assert не генерируется код и нет дополнительных затрат времени выполнения.

Бывают случаи, когда корректно вручную вызывать деструктор - вам это не понадобитсяпока вы не узнаете и не используете "размещение новых".

1 голос
/ 28 марта 2011

В дополнение к тому, что Эрик уже сказал:

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

...