请教Cstring += 崩溃问题

女神打Boss 2018-01-16 09:35:48
LONG CDDAAnalyzerDlg::OnSerialPortCommunication(WPARAM ch, LPARAM port)
{
str_myCommTemp.Format("%X", ch);
//遍历串口资源
for (int i = 0; i < COMMNUMBER; i++)
{
if (my_stuComm.b_comm[i])//已打开的串口
{
if (port == my_stuComm.i_commNum[i])//找对应的串口号
{
是这一句 my_stuComm.str_comm[i] += str_myCommTemp;//收到数据
my_stuComm.i_timeCount[i] = (int)TIMEOUT;//重置定时器计数
break;
}
}
}
return 0;
}
这个结构体
struct my_comminfo
{
int i_commNum[COMMNUMBER];//打开过的串口号
BOOL b_comm[COMMNUMBER];//与之对应的串口打开标志
CSerialPort my_SerialPort[COMMNUMBER];//串口资源对象
CString str_comm[COMMNUMBER];//串口收到数据
int i_timeCount[COMMNUMBER];//定时器计数
};
my_comminfo my_stuComm;
str_myCommTemp;//这是个Cstring类型成员变量
//调试崩溃断点
extern "C" _CRTIMP int __cdecl _CrtIsValidHeapPointer(
const void * pUserData
)
{
if (!pUserData)
return FALSE;

if (!_CrtIsValidPointer(pHdr(pUserData), sizeof(_CrtMemBlockHeader), FALSE))
return FALSE;

return HeapValidate( _crtheap, 0, pHdr(pUserData) );
}//断点在这



调用堆栈



其他说明,这是一个接收多个串口的消息响应函数,每个字符就触发一次这个函数,所以函数速度很快
崩溃的时间不定,可能是运行5分钟,可能是1小时

请问我该怎么解决,用什么方法替换 += ,或者 += 在使用时应注意什么细节







————————————————分割广告————————————————————————————
...全文
617 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
女神打Boss 2018-01-26
  • 打赏
  • 举报
回复
7楼可以解决这个问题 但是我内存增加的问题好像并没有解决,留这个坑以后再说吧
zgl7903 2018-01-18
  • 打赏
  • 举报
回复
DataDisplay 是不是有累计历史显示? 限制一个最大长度,超出这个长度 丢弃最前面的 运行一段时间后 设置断点停下来 查看字符串长度是否异常大, GDI句柄数、线程数等,如果无太大变化基本可认为正常, 运行1天1周再对比
女神打Boss 2018-01-18
  • 打赏
  • 举报
回复
引用 7 楼 zgl7903 的回复:
建议使用 CRITICAL_SECTION InitializeCriticalSection EnterCriticalSection LeaveCriticalSection DeleteCriticalSection
这样可以,但是有内存增加的现象,不用这个有时候可以运行1小时左右不会有内存增加,不知道为什么
赵4老师 2018-01-18
  • 打赏
  • 举报
回复
检查是否资源泄漏的办法之一: 在任务管理器 进程 查看 选择列 里面选择:内存使用、虚拟内存大小、句柄数、线程数、USER对象、GDI对象 让你的程序(进程)不退出,循环执行主流程很多遍,越多越好,比如1000000次甚至无限循环,记录以上各数值,再隔至少一小时,越长越好,比如一个月,再记录以上各数值。如果以上两组数值的差较大或随时间流逝不断增加,则铁定有对应资源的资源泄漏! 搜“GDI泄露检测”
女神打Boss 2018-01-18
  • 打赏
  • 举报
回复
引用 9 楼 zgl7903 的回复:
DataDisplay 是不是有累计历史显示? 限制一个最大长度,超出这个长度 丢弃最前面的 运行一段时间后 设置断点停下来 查看字符串长度是否异常大, GDI句柄数、线程数等,如果无太大变化基本可认为正常, 运行1天1周再对比
你说的这些在哪看
zgl7903 2018-01-16
  • 打赏
  • 举报
回复
可能 + 和 Empty 冲突了, 加锁试试看
女神打Boss 2018-01-16
  • 打赏
  • 举报
回复
引用 3 楼 oyljerry 的回复:
是不是数据同步等的问题。被同时修改读取,改坏地址了
这个好像有可能,我在一个定时器中使用了这个 ‘
//定时器处理
void CALLBACK CDDAAnalyzerDlg::my_TimeEvent(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)  
{
	CDDAAnalyzerDlg* mainDlg = (CDDAAnalyzerDlg*)dwUser;
	for (int i = 0; i < COMMNUMBER; i++)
	{
		if (mainDlg->my_stuComm.i_timeCount[i] <= 0 && mainDlg->my_stuComm.b_comm[i])//串口定时器计数小于等于0  //串口是打开的
		{
			//处理串口数据
			if (mainDlg->my_stuComm.str_comm[i] != "")//串口有数据
			{
				mainDlg->str_myTimerComm.Format("COM%dRecv:%s", mainDlg->my_stuComm.i_commNum[i], mainDlg->my_stuComm.str_comm[i]);
				mainDlg->DataDisplay(mainDlg->str_myTimerComm);///???
				mainDlg->my_stuComm.str_comm[i].Empty();//清空
			}
		}
		mainDlg->my_stuComm.i_timeCount[i]--;//定时器计数减1
	}
}
我该怎么处理呢,我已经有定时器计数来控制了,再加个互斥变量?
oyljerry 2018-01-16
  • 打赏
  • 举报
回复
是不是数据同步等的问题。被同时修改读取,改坏地址了
Eleven 2018-01-16
  • 打赏
  • 举报
回复
是不是有内存泄漏??
赵4老师 2018-01-16
  • 打赏
  • 举报
回复
不用CString,只用BYTE []或BYTE *不就完了。
女神打Boss 2018-01-16
  • 打赏
  • 举报
回复
//串口消息响应
LONG CDDAAnalyzerDlg::OnSerialPortCommunication(WPARAM ch, LPARAM port)
{
	str_myCommTemp.Format("%X", ch);
	//遍历串口资源
	for (int i = 0; i < COMMNUMBER; i++)
	{
		if (my_stuComm.b_comm[i])//已打开的串口
		{
			if (port == my_stuComm.i_commNum[i])//找对应的串口号
			{
				my_stuComm.b_strcomm[i] = FALSE;
				my_stuComm.str_comm[i] += str_myCommTemp;//收到数据
				my_stuComm.b_strcomm[i] = TRUE;
				my_stuComm.i_timeCount[i] = (int)TIMEOUT;//重置定时器计数
				break;
			}
		}
	}
	return 0;
}
//定时器处理
void CALLBACK CDDAAnalyzerDlg::my_TimeEvent(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)  
{
	CDDAAnalyzerDlg* mainDlg = (CDDAAnalyzerDlg*)dwUser;
	for (int i = 0; i < COMMNUMBER; i++)
	{
		if (mainDlg->my_stuComm.i_timeCount[i] <= 0 && mainDlg->my_stuComm.b_comm[i])//串口定时器计数小于等于0  //串口是打开的
		{
			//处理串口数据
			
			if (mainDlg->my_stuComm.str_comm[i] != "" && mainDlg->my_stuComm.b_strcomm[i])//串口有数据 //互斥变量判断
			{
				mainDlg->str_myTimerComm.Format("COM%dRecv:%s", mainDlg->my_stuComm.i_commNum[i], mainDlg->my_stuComm.str_comm[i]);
				mainDlg->DataDisplay(mainDlg->str_myTimerComm);///???
				//mainDlg->my_stuComm.str_comm[i].Empty();//清空
				mainDlg->my_stuComm.str_comm[i] = "";
			}
		}
		mainDlg->my_stuComm.i_timeCount[i]--;//定时器计数减1
	}
}
不知道我这样加的锁对不对

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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