- 论坛徽章:
- 0
|
回复 18楼 renstone921 的帖子
楼上的哥们,你仔细看清楚了,别动不动就摆出一付教训人的样子。
1〉我的意思是函数内string 对象里面的堆空间申请,而不是对象本身。这些基本的东西我就不跟你扯了,你了解得很透彻,但我未必没读过书,所以轮不到你头脑发热来教训俺
2> 你的这句话
====================================
如果调用pthread_exit(NULL),但对里面的string调用~string 那么内存正常
这条是胡说。你显式的调用一次析构函数,然后编译器产生代码调用一次析构函数,连续两次调用delete,如果析构函数在释放堆资源后,立即将指针成员置为NULL,不会出错。但如果连续针对某一指针调用delete,这时,堆结构已经破坏了。没有立即出错并不代表你的程序是正确的。
====================================
你说对了一半,说错了一半。编译器会调用析构函数没错,可关键编译器在什么时候调用析构函数?你敢肯定所有编译器都一样么?我的测试结果告诉我(linux redhat9.0+gcc 3.2.2环境下) C++对象超出他定义范围时,编译器自动调用析构函数,可现在问题就出在编译器并没有在pthread_exit(NULL)之前调用过析构函数!而当注释掉pthread_exit之后,则真正调用了析构函数(目前我的猜测是编译器自动调用析构函数应该是在goto,return,右大括符(})之前调用);所以你说的我在pthread_exit(NULL)之前显式调用string::~string()函数所以不会存在多次delete,废话不多说,我附上我的测试程序,您老人家倒杯茶回家慢慢测试去吧,记得gcc环境相同,别强词夺理,动不动胡说,动动手,再发言。中科院都说了,院士只代表在某方面做过杰出贡献,并不代表他在某方面是权威,尊重事实,尊重科学
3〉===牛人一般都是谨小慎微的先怀疑自己,狂牛先怀疑编译器。==对于您老的这句话,俺不懂,俺啥都不是,就想让程序能完成应该完成的工作,结果不对,我就需要不停的测试。这话您收回去吧,我这个问题已经测试好久了,本来是一个通信程序,发现内存泄漏,第一步就是花了大量时间测试自己的协议类是否有内存泄漏,然后测试自己的闲程框架,再后来查了好多资料才怀疑编译器。不过你怎么说都跟我没关系,我不聪明,做事比较傻,牛人谈不上,如门级程序员都不算,但我会实事求是,动手测试,结果才是最重要的
4〉=======做为一个成年人,把权力和义务分清楚。在论坛里,没有人有义务来帮你==== 这话俺不同意
论坛里面无所谓帮不帮,什么叫分享,什么叫共同讨论,什么叫共同测试,什么共同解决问题,这是我最喜欢的东西,动不动帮助、教育,俺就看不惯!如果你觉得这叫帮助我,你回家喝茶看自己笑话去吧!别来玷污我的心情!如果你把这里的每个问题当作一起解决、动手测试,或者说更加提高自身的编程修养,那么我就道歉,不好意思,说话比较冲,请多多包含。
下面附上测试程序,g++ 编译之后麻烦 通过./a.out >> mem.log来执行,至于程序怎么跑的,自己看吧
==================================================================
//不进行通信,直接运行空循环体
#include <stdio.h>
#include <iostream>
#include <vector>
#include <semaphore.h>
#include <pthread.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
using namespace std;
#define _MAXMASSAGECOUNT_ 1024*64
#define _STACK_SIZE_ 2UL*1024UL*1024UL
//事务条目
#define _AFFAIR_COUNT_ 5
#define _PHTREAD_DETCH_ PTHREAD_CREATE_JOINABLE
void exitFuction()
{
cout << "exit...." << endl;
}
class myTest
{
public:
myTest()
{
m_buf = new char[1024*1024];
memset(m_buf,0x0,1024*1024);
memset(m_buf,'a',1024*1024-1);
}
~myTest()
{
if( m_buf != NULL )
{
delete[] m_buf;
}
cout << "~myTest() is called" << endl;
}
protected:
char *m_buf;
};
//输出当前进程内存信息
void writeStatus()
{
if( getpid() <= 0 )
{
return;
}
char cmd[128];
memset(cmd,0x0,12 ;
sprintf(cmd,"/bin/cat /proc/%d/status",getpid());
cout << "=========" << cmd << "=========" << endl;
system(cmd);
return;
}
void* sendMsgs(void *arg)
{
cout << "child pthread start" << endl;
myTest getTest;
char buf[1024*1024];
memset(buf,0x0,1024*1024);
memset(buf,'a',1024*1024 - 1 );
writeStatus();
cout << "child end" << endl;
pthread_exit(NULL); //此处与return 轮回注释来测试是否调用了myTest::~myTest函数
//return NULL;
}
int main()
{
atexit(&exitFuction);
cout << "pragram started...." << endl;
writeStatus();
unsigned int i = 0;
/*
//测试进程内存空间
while( i < _AFFAIR_COUNT_ )
{
i ++;
cout << "\t" << i << ".fork start For" << endl;
writeStatus();
pid_t mypid = fork();
if( mypid > 0 )
{
//父进程
cout << "Father:fork good: " << mypid << endl;
cout << "wating Son...." << endl;
waitpid(mypid,NULL,0);
writeStatus();
}
else if( mypid == 0 )
{
//子进程
cout << "========Son start.....========" << endl;
writeStatus();
int j = 0;
string goodstr = "";
while( j < _MAXMASSAGECOUNT_ )
{
goodstr += "abcfefdasfadsdasffffffffffffffffafffffffffffffffffdaaaaaaaaafds";
j ++;
}
cout << "======================" << endl;
writeStatus();
cout << "=======Son end=========" << endl;
exit(0);
}
else
{
cout << " fork failture!" << strerror(errno) << endl;
}
}
i = 0;
cout << "fork end,started pthread... " << endl;
writeStatus();
*/
//测试线程内存空间
while( i < _AFFAIR_COUNT_ )
{
cout << i << endl;
writeStatus();
i ++;
int flag = 0;
pthread_attr_t pthread_attr;
pthread_attr_init(&pthread_attr);
void * addr = NULL;
addr = malloc(_STACK_SIZE_);
memset(addr,0x0,_STACK_SIZE_);
//pthread_attr_setdetachstate(&pthread_attr,_PHTREAD_DETCH_);
pthread_attr_setstack(&pthread_attr,addr,_STACK_SIZE_);
pthread_t threadSend;
if( (flag = pthread_create(&threadSend,&pthread_attr,&sendMsgs,NULL) != 0 ) )
{
cout << "create Error(threadSend):" << flag << endl;
free(addr);
pthread_attr_destroy(&pthread_attr);
break;
}
if( pthread_join(threadSend,NULL) == 0 )
{
cout << "child exit good" << endl;
}
else
{
cout << "child exit failture" << endl;
}
free(addr);
pthread_attr_destroy(&pthread_attr);
}
cout << "waiting ..." << endl;
writeStatus();
return -1;
} |
|