c++Void*でオブジェクトを解放するとどうなりますか?
3024 ワード
1月24日:前言:最近RTMPプッシュのDEMOを書いていますが、私はMessage Loopの形式でプッシュしています.ネットワークが悪いときに動的にパケットを失うためには、メッセージキューがバルブ値に達したときに以前のメッセージを捨てる必要があります.メッセージはint型にすぎませんが、Message Loopクラスを共通にするために、メッセージに対応するデータはVoidで、このとき動的にメッセージを失うとdelete Voidになります.私がこのコードを書いたとき、私は驚きました.これで本当にObject*オブジェクトを解放することができますか?
答えは?delete voidを直接使用すると、スペースが解放されます.これは実際にはc言語のfree機能と同じです.通常のポインタが解放されると、voidが指すメモリだけが解放されます.void*オブジェクトに他のポインタがある場合は、構造関数で解放することはできません.コードを使用して説明します.
ここで、delete pobjポインタの場合、myclassの構造関数を呼び出してdata*のスタックメモリを解放し、sizeof(myclass)サイズのスタックメモリを解放するため、メモリ漏洩は発生しません.このように使用すると、次のようになります.
ここでは、sizeof(myclass)サイズのスタックメモリのみが解放され、pobj->dataのブロックは解放されません.なぜですか.解析関数が呼び出されていないため!!!だから、delete voidを永遠に使わないで、すべてのwarning:deleting'void'is undefined[enabled by default]警告を除去してください!!実はここまでも同じ問題がありますが、なぜ親の構造関数をvirtual(虚関数)と宣言しますか?私はここで説明しないで、前の質問を引用して知っています.今、私が最初に出会った問題を簡単に話します.最初はshareを思い浮かべましたptrですが、考えてみると、これはテンプレートと同じようにデータ型を制限しており、handleと同じように虚関数を書いて、サブクラスに解放コードを実現させるしかないようです.短いコードを貼り付けます.
これはloop親クラスで、メッセージキューに制限はありません.
これは固定長loopサブクラスです.
1.29修正:寝槽、私はまるで知的障害者のようで、そんなに面倒ですか?データ型がわかりませんか?メッセージ・ベース・クラスは作成されません.他のメッセージは提供されたベース・クラスを継承しなければなりません.deleteベース・クラスを通じて派生クラスを解放することはできません.突然自分を軽蔑して、感じはこんなに长いc++を学んですべてむだに学んで、気持ちは比类がなくて复雑です・・・2.22:Loop类のソースコードはこの文章を読むことができます.
答えは?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类のソースコードはこの文章を読むことができます.