ページ 11

newしたクラスをdeleteしたい。

Posted: 2015年10月25日(日) 14:57
by ペンネーム
スレッド内部でnewしたクラスを必要がなくなったらdeleteする方法はありますでしょうか。

コード:

 
class1::func1(){
createthread(  ... thread1  );
}
class1::func2(){
class2のいろいろな処理をしてある程度時間がたって必要がなくなったので
class2をdeleteしたい。
}

thread1(){
class * __class2
__class2 = new class  ;
}

Re: newしたクラスをdeleteしたい。

Posted: 2015年10月26日(月) 04:02
by YuO
「必要がなくなったら」はどうやって判断するのでしょうか。
  • 判断する方法があって,判断するタイミングがあるならば,そのタイミングでdeleteすればよいです。
  • 判断する方法があって,判断するタイミングがないのであれば,判断するタイミングとして適する箇所を考えてそこで判断し,deleteすればよいです。
  • 判断する方法がないのであれば,どうしようもない,としか言いようがありません。
「必要がなくなったら」の条件次第では,スマートポインタ等を利用する事ができるかもしれません。

Re: newしたクラスをdeleteしたい。

Posted: 2015年10月26日(月) 06:59
by ペンネーム
ご回答ありがとうございます。
判断するタイミングは任意です。また、いつでもいいです。
現状class1はウィンドウプロシージャを持っていてとthread1とはスレッドが異なるのでthread1で作成したclass2にclass1からアクセスできません(そのとき作成したオブジェクトにアクセスできない。class1で別のオブジェクトとしてclass2をnewすることはできる。)。thread1内部では同じスレッドなのでclass2をdeleteすることはできますが、class1からdeleteできません。
タイミングは特に気にしてないのですが、クラスを作成したスレッドでない他のスレッドからdeleteする方法があるか考えています。
環境はvc++2012 非mfc、非atlで、ほぼwin32です。

Re: newしたクラスをdeleteしたい。

Posted: 2015年10月26日(月) 06:59
by ペンネーム
ご回答ありがとうございます。
判断するタイミングは任意です。また、いつでもいいです。
現状class1はウィンドウプロシージャを持っていてとthread1とはスレッドが異なるのでthread1で作成したclass2にclass1からアクセスできません(そのとき作成したオブジェクトにアクセスできない。class1で別のオブジェクトとしてclass2をnewすることはできる。)。thread1内部では同じスレッドなのでclass2をdeleteすることはできますが、class1からdeleteできません。
タイミングは特に気にしてないのですが、クラスを作成したスレッドでない他のスレッドからdeleteする方法があるか考えています。
環境はvc++2012 非mfc、非atlで、ほぼwin32です。

Re: newしたクラスをdeleteしたい。

Posted: 2015年10月26日(月) 11:05
by かずま
スレッドは、プロセスと違って、アドレス空間を共有するので、アドレスさえ
分かっていれば、クラスのオブジェクトの delete は簡単にできます。

コード:

#include <stdio.h>
#include <pthread.h> 
#include <unistd.h> 

class class2 {
public:
	class2() { printf("%p: class2 ctor\n", this); }
	~class2() { printf("%p: class2 dtor\n", this); }
};

class class1 {
public:
	class1() { printf("%p: class1 ctor\n", this); }
	~class1() { printf("%p: class1 dtor\n", this); }
	void func();   // thread1 を起動する
	void func2();  // class2 のオブジェクトを delete
	void func3();  // thread1 を停止する
	static void *thread1(void *param); // class2 のオブジェクトを new
private:
	pthread_t tid;
	class2 *c2;
	bool cancelThread;
};

void class1::func()
{
	pthread_create(&tid, 0,  thread1, this);
}

void class1::func2()
{
	//class2のいろいろな処理をしてある程度時間がたって必要がなくなったので
	//class2をdeleteしたい。
	delete c2;
}
 
void class1::func3()
{
	cancelThread = true;
	pthread_join(tid, 0);
}

void *class1::thread1(void *param)
{
	printf("thread1 started\n");
	class1 *c1 = (class1 *)param;

	class2 *__class2;
	__class2 = new class2;
	c1->c2 = __class2;
	for (int t = 10; t >= 0 && !c1->cancelThread; t--) {
		printf("thread1 running %d\n", t);
		sleep(1);
	}
	printf("thread1 stopped\n");
}

int main()
{
	class1 obj;
	obj.func();
	sleep(3);
	obj.func2();
	obj.func3();
}

Re: newしたクラスをdeleteしたい。

Posted: 2015年10月26日(月) 11:29
by かずま
失礼しました。
環境は Linux ではなく、Windows だったんですね。

コード:

#include <stdio.h>
#include <windows.h> 
 
class class2 {
public:
    class2() { printf("%p: class2 ctor\n", this); }
    ~class2() { printf("%p: class2 dtor\n", this); }
};
 
class class1 {
public:
    class1() { printf("%p: class1 ctor\n", this); }
    ~class1() { printf("%p: class1 dtor\n", this); }
    void func();   // thread1 を起動する
    void func2();  // class2 のオブジェクトを delete
    void func3();  // thread1 を停止する
    static DWORD WINAPI thread1(void *param); // class2 のオブジェクトを new
private:
    HANDLE th;
    DWORD tid;
    class2 *c2;
    bool cancelThread;
};
 
void class1::func()
{
    cancelThread = false;
    th = CreateThread(NULL, 0, thread1, this, 0, &tid);
}
 
void class1::func2()
{
    //class2のいろいろな処理をしてある程度時間がたって必要がなくなったので
    //class2をdeleteしたい。
    delete c2;
}
 
void class1::func3()
{
    cancelThread = true;
    WaitForSingleObject(th, INFINITE);
}
 
DWORD WINAPI class1::thread1(void *param)
{
    printf("thread1 started\n");
    class1 *c1 = (class1 *)param;
 
    class2 *__class2;
    __class2 = new class2;
    c1->c2 = __class2;
    for (int t = 10; t >= 0 && !c1->cancelThread; t--) {
        printf("thread1 running %d\n", t);
        Sleep(1000);
    }
    printf("thread1 stopped\n");
    return 0;
}
 
int main()
{
    class1 obj;
    obj.func();
    Sleep(3000);
    obj.func2();
    obj.func3();
}

Re: newしたクラスをdeleteしたい。

Posted: 2015年10月26日(月) 13:59
by ペンネーム
windowsのコードまでのせていただき大変ありがたいです。

こちらのコードが不完全なのでまだ、実現できていませんが、
スレッドを使用しない雛形でプライベートに保存したオブジェクトを削除するくだりは確認できました。
メモリが減る量が20MB→40MBにアップしました! ありがとうございました。

「スレッドは、プロセスと違って、アドレス空間を共有するので、アドレスさえ
分かっていれば、クラスのオブジェクトの delete は簡単にできます。」

まさにそのとおりですね。