多线程中多次new同一个指针对象的问题

DwyaneCV 2013-12-25 03:19:11

class CThreadParam //定义线程参数
{
public:
HANDLE hHandle; //线程句柄
CMultiTaskDlg *pDlg; //主窗口指针
int nPos; //对应任务列表中的位置
BOOL bStop; //线程是否停止
CThreadParam()
{
bStop = FALSE;
}
};


如图,是一个多线程的程序界面,每次点击新任务,都触发下面的程序
void CMultiTaskDlg::OnNewTask()
{
//创建新任务
CThreadParam* pParam = new CThreadParam;//这里每次都new一个CThreadParam可以吗?不会造成内存泄漏等问题????
pParam->pDlg = this;
int nCount = m_TaskList.GetItemCount();

int nPos = m_TaskList.InsertItem(nCount, "任务", 0);
CString szText;
szText.Format("任务%d", nPos);
m_TaskList.SetItemText(nPos, 0, szText);
m_TaskList.SetItemText(nPos, 2, "进行中...");
pParam->nPos = nPos;
pParam->hHandle = CreateThread(NULL, 0, TaskProc, pParam, 0, NULL);
m_HandleList.AddHead(pParam);
}


//下面是线程函数
DWORD __stdcall TaskProc(LPVOID lpParameter) //线程函数
{
CThreadParam Param;
memcpy(¶m, (CThreadParam *)lpParameter, sizeof(CThreadParam));
char szCounter[10] = {0};
int nPos = 0;
POSITION pos;
BOOL bTerminate = FALSE;
for(int i=0; i<500; i++)
{
memset(szCounter, 0, 10);
itoa(i, szCounter, 10);
Param.pDlg->FindItemPos(Param.hHandle, nPos, pos, bTerminate);
if (nPos != -1)
{
Param.pDlg->m_TaskList.SetItemText(nPos, 1, szCounter);
}
if (bTerminate)
{
goto label; //goto label;
}

Sleep(100); //延时,演示任务进行中
}


我是新手,可能我的想法是错的,我觉得每次new一个,自然应该delete,但是在这个多线程中,每次new一次再delete,就不能实现界面中新建任务的要求,但是又觉得new一个应该有对应的delete。所以一直对这段程序代码有疑惑
难道new一次,不一定要delete????
...全文
826 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
worldy 2013-12-25
  • 打赏
  • 举报
回复
引用 6 楼 dwyaneyywade 的回复:
[quote=引用 4 楼 worldy 的回复:] CThreadParam* pParam = new CThreadParam;//这里每次都new一个CThreadParam可以吗?不会造成内存泄漏等问题???? //不是定义static的,就可以,每个线程其局部变量都是独立的
引用 4 楼 worldy 的回复:
CThreadParam* pParam = new CThreadParam;//这里每次都new一个CThreadParam可以吗?不会造成内存泄漏等问题???? //不是定义static的,就可以,每个线程其局部变量都是独立的
那对于单线程,是不是就不可以啦?对于单线程,每次new一次,在下一次new之前一定要delete,对于多线程则可以多次new,是不是这样啊?谢谢[/quote] 单线程是多线程的一种特殊情况,同样也可以这样,为什么不可以,一个函数中new一个指针,不一定得在该函数中delete,比如链表节点,按照需要调用一个函数n次,new了n个节点,当不再使用该链表的时候,一起销毁所有的节点 只要你new出来的内存是可以跟踪的,就不一定在下次new之前需要delete
DwyaneCV 2013-12-25
  • 打赏
  • 举报
回复
引用 5 楼 worldy 的回复:
创建线程时申请的空间,可以在线程函数中,在不再使用的时候释放,比如下面中红色位置 void CMultiTaskDlg::OnNewTask() { //创建新任务 CThreadParam* pParam = new CThreadParam;//这里每次都new一个CThreadParam可以吗?不会造成内存泄漏等问题???? pParam->pDlg = this; int nCount = m_TaskList.GetItemCount(); int nPos = m_TaskList.InsertItem(nCount, "任务", 0); CString szText; szText.Format("任务%d", nPos); m_TaskList.SetItemText(nPos, 0, szText); m_TaskList.SetItemText(nPos, 2, "进行中..."); pParam->nPos = nPos; pParam->hHandle = CreateThread(NULL, 0, TaskProc, pParam, 0, NULL); m_HandleList.AddHead(pParam); } //下面是线程函数 DWORD __stdcall TaskProc(LPVOID lpParameter) //线程函数 { CThreadParam Param; memcpy(¶m, (CThreadParam *)lpParameter, sizeof(CThreadParam)); char szCounter[10] = {0}; int nPos = 0; POSITION pos; BOOL bTerminate = FALSE; for(int i=0; i<500; i++) { memset(szCounter, 0, 10); itoa(i, szCounter, 10); Param.pDlg->FindItemPos(Param.hHandle, nPos, pos, bTerminate); if (nPos != -1) { Param.pDlg->m_TaskList.SetItemText(nPos, 1, szCounter); } if (bTerminate) { goto label; //goto label; } Sleep(100); //延时,演示任务进行中 } delete lpParameter;
加了您这段代码,可以运行,原程序上没加,我觉得还是加上比较好。谢谢啦
DwyaneCV 2013-12-25
  • 打赏
  • 举报
回复
引用 4 楼 worldy 的回复:
CThreadParam* pParam = new CThreadParam;//这里每次都new一个CThreadParam可以吗?不会造成内存泄漏等问题???? //不是定义static的,就可以,每个线程其局部变量都是独立的
引用 4 楼 worldy 的回复:
CThreadParam* pParam = new CThreadParam;//这里每次都new一个CThreadParam可以吗?不会造成内存泄漏等问题???? //不是定义static的,就可以,每个线程其局部变量都是独立的
那对于单线程,是不是就不可以啦?对于单线程,每次new一次,在下一次new之前一定要delete,对于多线程则可以多次new,是不是这样啊?谢谢
worldy 2013-12-25
  • 打赏
  • 举报
回复
创建线程时申请的空间,可以在线程函数中,在不再使用的时候释放,比如下面中红色位置 void CMultiTaskDlg::OnNewTask() { //创建新任务 CThreadParam* pParam = new CThreadParam;//这里每次都new一个CThreadParam可以吗?不会造成内存泄漏等问题???? pParam->pDlg = this; int nCount = m_TaskList.GetItemCount(); int nPos = m_TaskList.InsertItem(nCount, "任务", 0); CString szText; szText.Format("任务%d", nPos); m_TaskList.SetItemText(nPos, 0, szText); m_TaskList.SetItemText(nPos, 2, "进行中..."); pParam->nPos = nPos; pParam->hHandle = CreateThread(NULL, 0, TaskProc, pParam, 0, NULL); m_HandleList.AddHead(pParam); } //下面是线程函数 DWORD __stdcall TaskProc(LPVOID lpParameter) //线程函数 { CThreadParam Param; memcpy(¶m, (CThreadParam *)lpParameter, sizeof(CThreadParam)); char szCounter[10] = {0}; int nPos = 0; POSITION pos; BOOL bTerminate = FALSE; for(int i=0; i<500; i++) { memset(szCounter, 0, 10); itoa(i, szCounter, 10); Param.pDlg->FindItemPos(Param.hHandle, nPos, pos, bTerminate); if (nPos != -1) { Param.pDlg->m_TaskList.SetItemText(nPos, 1, szCounter); } if (bTerminate) { goto label; //goto label; } Sleep(100); //延时,演示任务进行中 } delete lpParameter;
worldy 2013-12-25
  • 打赏
  • 举报
回复
CThreadParam* pParam = new CThreadParam;//这里每次都new一个CThreadParam可以吗?不会造成内存泄漏等问题???? //不是定义static的,就可以,每个线程其局部变量都是独立的
zhuobattle 2013-12-25
  • 打赏
  • 举报
回复
引用 2 楼 dwyaneyywade 的回复:
[quote=引用 1 楼 zhuobattle 的回复:] new和delete当然要一一对应,但可以在其它地方delete.比如在你每个线程结束的时候。 或者你不怕内存涨得太多,可以在程序退出的时候,因为我看你有把结果放在m_HandleList。 如果是在线程退出的时候delete掉了,那么你就不要放在m_HandleList里,因为这时已经是野指针了
使得,在点击终止按钮时,触发delete指针的程序。 但是原程序中每次点击新任务按钮,都会new一次,而每次new,并不会去delete,这样可以???[/quote] 我前面说了,所有的指针都保存在你的那个list里,退出的时候你会统释放掉的。但如果这个param用过一次就没用了,不建议你最后释放,你在threadfunc退出时delete就可以了
DwyaneCV 2013-12-25
  • 打赏
  • 举报
回复
引用 1 楼 zhuobattle 的回复:
new和delete当然要一一对应,但可以在其它地方delete.比如在你每个线程结束的时候。 或者你不怕内存涨得太多,可以在程序退出的时候,因为我看你有把结果放在m_HandleList。 如果是在线程退出的时候delete掉了,那么你就不要放在m_HandleList里,因为这时已经是野指针了
使得,在点击终止按钮时,触发delete指针的程序。 但是原程序中每次点击新任务按钮,都会new一次,而每次new,并不会去delete,这样可以???
zhuobattle 2013-12-25
  • 打赏
  • 举报
回复
new和delete当然要一一对应,但可以在其它地方delete.比如在你每个线程结束的时候。 或者你不怕内存涨得太多,可以在程序退出的时候,因为我看你有把结果放在m_HandleList。 如果是在线程退出的时候delete掉了,那么你就不要放在m_HandleList里,因为这时已经是野指针了

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧