c++Void*でオブジェクトを解放するとどうなりますか?

3024 ワード

1月24日:前言:最近RTMPプッシュのDEMOを書いていますが、私はMessage Loopの形式でプッシュしています.ネットワークが悪いときに動的にパケットを失うためには、メッセージキューがバルブ値に達したときに以前のメッセージを捨てる必要があります.メッセージはint型にすぎませんが、Message Loopクラスを共通にするために、メッセージに対応するデータはVoidで、このとき動的にメッセージを失うとdelete Voidになります.私がこのコードを書いたとき、私は驚きました.これで本当にObject*オブジェクトを解放することができますか?
答えは?delete voidを直接使用すると、スペースが解放されます.これは実際にはc言語のfree機能と同じです.通常のポインタが解放されると、voidが指すメモリだけが解放されます.void*オブジェクトに他のポインタがある場合は、構造関数で解放することはできません.コードを使用して説明します.
class mycalss  
{  
public:  
mycalss() : data(new int[100]){}  
    ~mycalss()  
    {  
        delete[] data;  
    }  
private:  
int *data;  
};  
int main()  
{  
mycalss* pobj =new mycalss;  
delete pobj;  
return 0;  
}  

ここで、delete pobjポインタの場合、myclassの構造関数を呼び出してdata*のスタックメモリを解放し、sizeof(myclass)サイズのスタックメモリを解放するため、メモリ漏洩は発生しません.このように使用すると、次のようになります.
int main()  
{  
void* pobj = new mycalss;  
delete pobj;  
return 0;  
}  

ここでは、sizeof(myclass)サイズのスタックメモリのみが解放され、pobj->dataのブロックは解放されません.なぜですか.解析関数が呼び出されていないため!!!だから、delete voidを永遠に使わないで、すべてのwarning:deleting'void'is undefined[enabled by default]警告を除去してください!!実はここまでも同じ問題がありますが、なぜ親の構造関数をvirtual(虚関数)と宣言しますか?私はここで説明しないで、前の質問を引用して知っています.今、私が最初に出会った問題を簡単に話します.最初はshareを思い浮かべましたptrですが、考えてみると、これはテンプレートと同じようにデータ型を制限しており、handleと同じように虚関数を書いて、サブクラスに解放コードを実現させるしかないようです.短いコードを貼り付けます.
class looper {
    public:
        looper();
        virtual ~looper();

        //flush         
        void post(int what, void *data, bool flush = false);
        void quit();
        virtual void handle(int what, void *data);
    private:
        virtual void addmsg(loopermessage *msg, bool flush);
        static void* trampoline(void* p);
        void loop();
    protected:
        std::deque< loopermessage * > _msgQueue;
        pthread_t worker;
        sem_t headwriteprotect;
        sem_t headdataavailable;
        bool running;
};

これはloop親クラスで、メッセージキューに制限はありません.
//    loop,  loop,      
  class FixedLoop: public looper
  {
  public:
    FixedLoop(int messageLen);
  private:
   virtual void eraseMsg(int what, void *data);
   virtual void addmsg(loopermessage *msg, bool flush)
  {
    sem_wait(&headwriteprotect);
    if (flush) {
        _msgQueue.clear();
    }
    LOGV("size =%d max =%d",_msgQueue.size(),_MaxMsgLen);
    if(_msgQueue.size() >= _MaxMsgLen)  //      
    {
        loopermessage *tempMsg =  _msgQueue.front();
        _msgQueue.pop_front();
        eraseMsg(tempMsg->what,tempMsg->obj);
        delete tempMsg;
    }
    _msgQueue.push_back(msg);
    LOGV("post msg %d", msg->what);
    sem_post(&headwriteprotect);
    sem_post(&headdataavailable);
  }
  private:
   int _MaxMsgLen;
  };

これは固定長loopサブクラスです.
1.29修正:寝槽、私はまるで知的障害者のようで、そんなに面倒ですか?データ型がわかりませんか?メッセージ・ベース・クラスは作成されません.他のメッセージは提供されたベース・クラスを継承しなければなりません.deleteベース・クラスを通じて派生クラスを解放することはできません.突然自分を軽蔑して、感じはこんなに长いc++を学んですべてむだに学んで、気持ちは比类がなくて复雑です・・・2.22:Loop类のソースコードはこの文章を読むことができます.