一、前言
在理论零碎中,用户晓得产生了什么事件的流程可能是:底层驱动检测到事件——上抛到对应模块解决——弹窗或者其余形式让用户可见。然而事件很多种,有时候不能确认事件中某一个字段值的长度,而间接申请最大长度的话,如果很大的话比拟节约内存空间。因而可能会应用上面的形式定义事件的相干信息:
typedef struct{ ... uint64_t reserved1; //预留 uint64_t reserved2; //预留 uint32_t info_size; uint8_t event_info[0]; }REVENT_INFO,*PREVENT_INFO;
event_info字段是不定长度的。这种状况下,不论是设置值还是获取值,咱们都须要申请对应大小的空间,如果
memcpy(event->event_info, pEventInfo, nLen);
除非没有其余调用应用到这块内存,否则可能发现意料之外的问题。
二、解决
鉴于以上阐明,不论是设置还是获取,咱们最好都先申请一块内存,用来保留事件的信息。
以下流程以设置为例进行阐明。
1、申请内存空间
CString strEventInfo = Dlg.m_strEventInfo;CStringA strData(strEventInfo);int nLen = strData.GetLength(); //调用输出的内容长度int nEventInfoSize = sizeof(REVENT_INFO) + nLen;char* pEventInfo = new(std::nothrow) char[nEventInfoSize + 1];if (NULL == pEventInfo){ return ;}ZeroMemory(pEventInfo, nEventInfoSize + 1);PREVENT_INFO pEvent = (PREVENT_INFO )pEventInfo;const char* pInfo = strData.GetString();memcpy(pEvent->event_info, pInfo, nLen);pEvent->info_size = nLen;...delete[] pEvent;pEvent = NULL;
这里为什么将CString转为CStringA呢?当用户输出的内容蕴含中文或者其余字符时,能正确设置内容;如果不转的话,字符串中含有中文等,非英文字符的状况下,可能用户设置的值和实在设置的值不统一,因为中文字符和英文字符的字节长度不统一。
因为pEvent的内存是new进去,因而在应用完了之后,最好应用delete开释掉,若不开释的话,在频繁调用状况,内存增长很快,到肯定状况下,可能导致其余调用申请内存空间失败。