乐趣区

关于数据结构:数据结构中含有可变长度字段处理

一、前言

在理论零碎中,用户晓得产生了什么事件的流程可能是:底层驱动检测到事件——上抛到对应模块解决——弹窗或者其余形式让用户可见。然而事件很多种,有时候不能确认事件中某一个字段值的长度,而间接申请最大长度的话,如果很大的话比拟节约内存空间。因而可能会应用上面的形式定义事件的相干信息:

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 开释掉,若不开释的话,在频繁调用状况,内存增长很快,到肯定状况下,可能导致其余调用申请内存空间失败。

退出移动版