OnPaint里的new后内存怎么办,在线等!!!

ningto.com 2011-08-03 02:09:27
在OnPaint里画图需要new一个写好了的画图的类,现在有两个问题:
部分代码如下:

LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
PAINTSTRUCT ps;

HDC hdc = BeginPaint(&ps);

m_spObj = new CSpScheme(hdc);

m_spObj->DrawBk(...);
...
...
EndPaint(&ps);
return 0;
}

1>我上面这样写的话运行是好好的,但是会不会造成内存泄露啊?为什么?
2>还有如果在返回之前delete的话,运行会出问题的,希望高手能详细解释一下,感觉OnPaint里new有些特殊,毕竟这个函数窗口一重绘就要执行的
...全文
140 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
ningto.com 2011-08-03
  • 打赏
  • 举报
回复
测试了第二个析构函数没问题,是其他问题,结贴了
alexander_david 2011-08-03
  • 打赏
  • 举报
回复
第二个析构函数还有问题?不明白了。
ningto.com 2011-08-03
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 alexander_david 的回复:]

你的那个初始化函数是在构造函数内调用的吗?还有那个memset的第三个参数不对的,
sizeof(m_szInitials[i]));返回的值是4,这样只将前4个字节置零。

memset(m_szInitials[i], 0, sizeof(wchar_t) * KEY_LEN);

你的第二个析构函数我觉得是没有问题的。
[/Quote]
你说的是对的,不过析构函数还是有问题
alexander_david 2011-08-03
  • 打赏
  • 举报
回复
你的那个初始化函数是在构造函数内调用的吗?还有那个memset的第三个参数不对的,
sizeof(m_szInitials[i]));返回的值是4,这样只将前4个字节置零。

memset(m_szInitials[i], 0, sizeof(wchar_t) * KEY_LEN);

你的第二个析构函数我觉得是没有问题的。
ningto.com 2011-08-03
  • 打赏
  • 举报
回复
13楼那个问题怎么释放掉啊
CSharp_XinBing 2011-08-03
  • 打赏
  • 举报
回复
OnDraw里最好只是使用数据,而不生成数据最好。
生成改变数据在其它函数中。
ningto.com 2011-08-03
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 alexander_david 的回复:]

不妨检查一下CSpScheme的析构函数。
[/Quote]
确是这个析构函数有问题,问一下这个怎么析构:

成员变量:
wchar_t *m_szInitials[KEY_COUNT];
wchar_t *m_szFinals1[KEY_COUNT];
wchar_t *m_szFinals2[KEY_COUNT];

初始化:
for (int i = 0; i < KEY_COUNT; i++)
{
m_szInitials[i] = (wchar_t *)malloc(sizeof(wchar_t) * KEY_LEN);
memset(m_szInitials[i], 0, sizeof(m_szInitials[i]));
m_szFinals1[i] = (wchar_t *)malloc(sizeof(wchar_t) * KEY_LEN);
memset(m_szFinals1[i], 0, sizeof(m_szFinals1[i]));
m_szFinals2[i] = (wchar_t *)malloc(sizeof(wchar_t) * KEY_LEN);
memset(m_szFinals2[i], 0, sizeof(m_szFinals2[i]));
}


请问那三个成员变量怎么析构掉?
我下面两种都试了不行:

1>
free(m_szInitials);
free(m_szFinals1);
free(m_szFinals2);
2>
for (int i = 0; i < KEY_COUNT; i++)
{
if (m_szInitials[i])
{
free(m_szInitials[i]);
m_szInitials[i] = NULL;
}
if (m_szFinals1[i])
{
free(m_szFinals1[i]);
m_szFinals1[i] = NULL;
}
if (m_szFinals2[i])
{
free(m_szFinals2[i]);
m_szFinals2[i] = NULL;
}
}
shiyunqiang 2011-08-03
  • 打赏
  • 举报
回复
界面没更新一次就调用一次OnPaint函数,就需要创建一次类,有没有及时删除,发生泄漏是必然的。
向立天 2011-08-03
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 tujiaw 的回复:]

引用 5 楼 xianglitian 的回复:

delete会有什么问题

我画图的这个对话框是点击按钮后弹出来的模态对话框,如果加delete的话,我一点按钮就报:
Unhandled exception at 0xxxxxxx...: User breakpoint.
[/Quote] CSpScheme是什么?
alexander_david 2011-08-03
  • 打赏
  • 举报
回复
不妨检查一下CSpScheme的析构函数。
ningto.com 2011-08-03
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 whuhhz 的回复:]

那肯定内存会泄露了,每次刷新都会new CSpScheme(hdc),如果m_spObj是类的成员变量,在构造函数中
m_spObj = NULL,析构函数中if (m_spObj) delete m_spObj; m_spObj = NULL;

你的OnPaint中,改为if (!m_spObj) m_spObj = new CSpScheme(hdc);就不会有内存泄露了。
[/Quote]
我也试过这样的,可是图被其他窗口覆盖后就不重绘了,变成了空白
ningto.com 2011-08-03
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 xianglitian 的回复:]

delete会有什么问题
[/Quote]
我画图的这个对话框是点击按钮后弹出来的模态对话框,如果加delete的话,我一点按钮就报:
Unhandled exception at 0xxxxxxx...: User breakpoint.
ningto.com 2011-08-03
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 visualeleven 的回复:]

引用 2 楼 tujiaw 的回复:
引用 1 楼 tompaz 的回复:

当然会出问题,直接用栈变量试试
new是统一的,不可能在哪个函数里不一样

m_spObj这个是指针类型的成员变量,用栈会造成其他问题,最好不用栈,在我那个基础上最好是添代码,不要改代码。

那你的new放在外面,不要放到OnPaint中,不需要的地方在delete
[/Quote]
放在外面我传不进去DC
一桶姜山 2011-08-03
  • 打赏
  • 举报
回复
在构造函数中:m_spObj = NULL;

在OnPaint中:
if(m_spObj==0)m_spObj = new CSpScheme(hdc);

向立天 2011-08-03
  • 打赏
  • 举报
回复
delete会有什么问题
Eleven 2011-08-03
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 tujiaw 的回复:]
引用 1 楼 tompaz 的回复:

当然会出问题,直接用栈变量试试
new是统一的,不可能在哪个函数里不一样

m_spObj这个是指针类型的成员变量,用栈会造成其他问题,最好不用栈,在我那个基础上最好是添代码,不要改代码。
[/Quote]
那你的new放在外面,不要放到OnPaint中,不需要的地方在delete
whuhhz 2011-08-03
  • 打赏
  • 举报
回复
那肯定内存会泄露了,每次刷新都会new CSpScheme(hdc),如果m_spObj是类的成员变量,在构造函数中
m_spObj = NULL,析构函数中if (m_spObj) delete m_spObj; m_spObj = NULL;

你的OnPaint中,改为if (!m_spObj) m_spObj = new CSpScheme(hdc);就不会有内存泄露了。
ningto.com 2011-08-03
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 tompaz 的回复:]

当然会出问题,直接用栈变量试试
new是统一的,不可能在哪个函数里不一样
[/Quote]
m_spObj这个是指针类型的成员变量,用栈会造成其他问题,最好不用栈,在我那个基础上最好是添代码,不要改代码。
tompaz 2011-08-03
  • 打赏
  • 举报
回复
当然会出问题,直接用栈变量试试
new是统一的,不可能在哪个函数里不一样
使用VC++6.0做开发工具, 采用简单的SDI框架结构 ,一次处理一幅位图(有兴趣的可以作成MDI) 1)位图信息的数据是从左下往右下为一行,一行一行往上排的。 2)每行像素应该是4的倍数,不足的地方用空点补齐,读的时候注意跳过冗余点。 3)主要数据都存在Doc面,BMP的主要数据存在一个由ImgData指向的BYTE型的内存空间(根据位图的大小,动态分配的)。 4)数据读进来以后,注 意向内存中贴图,以保证刷新的效率。 5)程序执行流程 应用程序生成--》打开--》CDipView的OnFileOpen 函数--》 调用CDipDoc的FileOpen 函数--》并使用myDoc->UpdateAllViews(NULL); 刷新 自动调用CDipView的OnPaint函数--》调用CDipView的OnDraw函数----一个像素点一个像素点的画 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 比较重要的地方 读BMP文件,只能打开256色 (可以是灰度) 显示和内存贴图技术 关于调色板: 调色板实际上是一个数组,4个BYTE 分别是 B,G,R,和 Reserved 每一个像素点都有一个相应的数组。 关于VC和windows 的绘图机制: 使用GDI(图形设备接口)对象,通常使用CDC 类,CPaintDC也一样(device-context)设备上下文 windows下的MFC编程机制,消息驱动,事件等待! 全局的app(应用程序对象) 注意 手工分配内存的清除 和CDC对象的删除 以释放系统的GDI资源 每一个new操作符都要对应一个delete 虽然已经弄出来了,还是希望大家好好读读源程序。 你们以后的工作: 在菜单中添加菜单项,通过ClassWizzard 生成消息响应函数(当然也可手动添加), 所有的操作应当是对 BYTE* ImgData;进行的。 在完成相应的功能后 将 isnewfile 和 isnewiamge 置为真 ,并使用myDoc->UpdateAllViews(NULL); 刷新 当然,可以更加有个性化一点,有能力的同学可以自己完成。 随着课程的进行,菜单功能逐渐丰富,最后完成基本的数字图像处理的功能,而不必最后一下完成一个大的作业。
VC++6.0车牌识别系统 需要注意的地方: 使用VC++6.0做开发工具, 采用简单的SDI框架结构 ,一次处理一幅位图(有兴趣的可以作成MDI) 1)位图信息的数据是从左下往右下为一行,一行一行往上排的。 2)每行像素应该是4的倍数,不足的地方用空点补齐,读的时候注意跳过冗余点。 3)主要数据都存在Doc面,BMP的主要数据存在一个由ImgData指向的BYTE型的内存空间(根据位图的大小,动态分配的)。 4)数据读进来以后,注意向内存中贴图,以保证刷新的效率。 5)程序执行流程 应用程序生成--》打开--》CDipView的OnFileOpen 函数--》 调用CDipDoc的FileOpen 函数--》并使用myDoc->UpdateAllViews(NULL); 刷新 自动调用CDipView的OnPaint函数--》调用CDipView的OnDraw函数----一个像素点一个像素点的画 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 比较重要的地方 读BMP文件,只能打开256色 (可以是灰度) 显示和内存贴图技术 关于调色板: 调色板实际上是一个数组,4个BYTE 分别是 B,G,R,和 Reserved 每一个像素点都有一个相应的数组。 关于VC和windows 的绘图机制: 使用GDI(图形设备接口)对象,通常使用CDC 类,CPaintDC也一样(device-context)设备上下文 windows下的MFC编程机制,消息驱动,事件等待! 全局的app(应用程序对象) 注意 手工分配内存的清除 和CDC对象的删除 以释放系统的GDI资源 每一个new操作符都要对应一个delete 虽然已经弄出来了,还是希望大家好好读读源程序。 你们以后的工作: 在菜单中添加菜单项,通过ClassWizzard 生成消息响应函数(当然也可手动添加), 所有的操作应当是对 BYTE* ImgData;进行的。 在完成相应的功能后 将 isnewfile 和 isnewiamge 置为真 ,并使用myDoc->UpdateAllViews(NULL); 刷新 当然,可以更加有个性化一点,有能力的同学可以自己完成。 随着课程的进行,菜单功能逐渐丰富,最后完成基本的数字图像处理的功能,而不必最后一下完成一个大的作业。
使用VC++6.0做开发工具, 采用简单的SDI框架结构 ,一次处理一幅位图(有兴趣的可以作成MDI) 1)位图信息的数据是从左下往右下为一行,一行一行往上排的。 2)每行像素应该是4的倍数,不足的地方用空点补齐,读的时候注意跳过冗余点。 3)主要数据都存在Doc面,BMP的主要数据存在一个由ImgData指向的BYTE型的内存空间(根据位图的大小,动态分配的)。 4)数据读进来以后,注意向内存中贴图,以保证刷新的效率。 5)程序执行流程 应用程序生成--》打开--》CDipView的OnFileOpen 函数--》 调用CDipDoc的FileOpen 函数--》并使用myDoc->UpdateAllViews(NULL); 刷新 自动调用CDipView的OnPaint函数--》调用CDipView的OnDraw函数----一个像素点一个像素点的画 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 比较重要的地方 读BMP文件,只能打开256色 (可以是灰度) 显示和内存贴图技术 关于调色板: 调色板实际上是一个数组,4个BYTE 分别是 B,G,R,和 Reserved 每一个像素点都有一个相应的数组。 关于VC和windows 的绘图机制: 使用GDI(图形设备接口)对象,通常使用CDC 类,CPaintDC也一样(device-context)设备上下文 windows下的MFC编程机制,消息驱动,事件等待! 全局的app(应用程序对象) 注意 手工分配内存的清除 和CDC对象的删除 以释放系统的GDI资源 每一个new操作符都要对应一个delete 虽然已经弄出来了,还是希望大家好好读读源程序。 你们以后的工作: 在菜单中添加菜单项,通过ClassWizzard 生成消息响应函数(当然也可手动添加), 所有的操作应当是对 BYTE* ImgData;进行的。 在完成相应的功能后 将 isnewfile 和 isnewiamge 置为真 ,并使用myDoc->UpdateAllViews(NULL); 刷新 当然,可以更加有个性化一点,有能力的同学可以自己完成。 随着课程的进行,菜单功能逐渐丰富,最后完成基本的数字图像处理的功能,而不必最后一下完成一个大的作业。
需要注意的地方: 使用VC++6.0做开发工具, 采用简单的SDI框架结构 ,一次处理一幅位图(有兴趣的可以作成MDI) 1)位图信息的数据是从左下往右下为一行,一行一行往上排的。 2)每行像素应该是4的倍数,不足的地方用空点补齐,读的时候注意跳过冗余点。 3)主要数据都存在Doc面,BMP的主要数据存在一个由ImgData指向的BYTE型的内存空间(根据位图的大小,动态分配的)。 4)数据读进来以后,注意向内存中贴图,以保证刷新的效率。 5)程序执行流程 应用程序生成--》打开--》CDipView的OnFileOpen 函数--》 调用CDipDoc的FileOpen 函数--》并使用myDoc->UpdateAllViews(NULL); 刷新 自动调用CDipView的OnPaint函数--》调用CDipView的OnDraw函数----一个像素点一个像素点的画 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 比较重要的地方 读BMP文件,只能打开256色 (可以是灰度) 显示和内存贴图技术 关于调色板: 调色板实际上是一个数组,4个BYTE 分别是 B,G,R,和 Reserved 每一个像素点都有一个相应的数组。 关于VC和windows 的绘图机制: 使用GDI(图形设备接口)对象,通常使用CDC 类,CPaintDC也一样(device-context)设备上下文 windows下的MFC编程机制,消息驱动,事件等待! 全局的app(应用程序对象) 注意 手工分配内存的清除 和CDC对象的删除 以释放系统的GDI资源 每一个new操作符都要对应一个delete 虽然已经弄出来了,还是希望大家好好读读源程序。 你们以后的工作: 在菜单中添加菜单项,通过ClassWizzard 生成消息响应函数(当然也可手动添加), 所有的操作应当是对 BYTE* ImgData;进行的。 在完成相应的功能后 将 isnewfile 和 isnewiamge 置为真 ,并使用myDoc->UpdateAllViews(NULL); 刷新 当然,可以更加有个性化一点,有能力的同学可以自己完成。 随着课程的进行,菜单功能逐渐丰富,最后完成基本的数字图像处理的功能,而不必最后一下完成一个大的作业。
需要注意的地方: 使用VC++6.0做开发工具, 采用简单的SDI框架结构 ,一次处理一幅位图(有兴趣的可以作成MDI) 1)位图信息的数据是从左下往右下为一行,一行一行往上排的。 2)每行像素应该是4的倍数,不足的地方用空点补齐,读的时候注意跳过冗余点。 3)主要数据都存在Doc面,BMP的主要数据存在一个由ImgData指向的BYTE型的内存空间(根据位图的大小,动态分配的)。 4)数据读进来以后,注意向内存中贴图,以保证刷新的效率。 5)程序执行流程 应用程序生成--》打开--》CDipView的OnFileOpen 函数--》 调用CDipDoc的FileOpen 函数--》并使用myDoc->UpdateAllViews(NULL); 刷新 自动调用CDipView的OnPaint函数--》调用CDipView的OnDraw函数----一个像素点一个像素点的画 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 比较重要的地方 读BMP文件,只能打开256色 (可以是灰度) 显示和内存贴图技术 关于调色板: 调色板实际上是一个数组,4个BYTE 分别是 B,G,R,和 Reserved 每一个像素点都有一个相应的数组。 关于VC和windows 的绘图机制: 使用GDI(图形设备接口)对象,通常使用CDC 类,CPaintDC也一样(device-context)设备上下文 windows下的MFC编程机制,消息驱动,事件等待! 全局的app(应用程序对象) 注意 手工分配内存的清除 和CDC对象的删除 以释放系统的GDI资源 每一个new操作符都要对应一个delete 虽然已经弄出来了,还是希望大家好好读读源程序。 你们以后的工作: 在菜单中添加菜单项,通过ClassWizzard 生成消息响应函数(当然也可手动添加), 所有的操作应当是对 BYTE* ImgData;进行的。 在完成相应的功能后 将 isnewfile 和 isnewiamge 置为真 ,并使用myDoc->UpdateAllViews(NULL); 刷新 当然,可以更加有个性化一点,有能力的同学可以自己完成。 随着课程的进行,菜单功能逐渐丰富,最后完成基本的数字图像处理的功能,而不必最后一下完成一个大的作业。

15,979

社区成员

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

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