拥抱正能量,遇见更好的自己:樱花盛开时,你会感谢今天的我
memcpy深度解æ��resistancevsresistance关键区别一ã€�æœ¬è´¨åŒºåˆ«ç›®æ ‡åœ°å�€çš„ä¸�å�Œå�«ä¹‰
å†…å˜æ“�作示æ„�图graph LRS[æº�æ•°æ�®] --|memcpy| D[ç›®æ ‡åœ°å�€]subgraph 场景1memcpy(resistance, …)A[resistanceå�˜é‡�] --|resistance å�–地å�€| D1[å�˜é‡�内å˜ä½�ç½®]endsubgraph 场景2memcpy(resistance, …)B[resistance指针] --|resistance 指针值| D2[指针指å�‘的内å˜åŒºåŸŸ]end
æ ¸å¿ƒåŒºåˆ«å¯¹æ¯”è¡¨ç‰¹æ€§memcpy(resistance, src, size)memcpy(resistance, src, size)ç›®æ ‡ç±»å�‹å�˜é‡�地å�€æŒ‡é’ˆå�˜é‡�æ“�作对象resistanceå�˜é‡�本身resistance指针指å�‘的内å˜åŒºåŸŸå†…å˜å½±å“�ç›´æ�¥ä¿®æ”¹resistance的值修改resistance指å�‘的数æ�®å…¸å�‹ç”¨é€”填充局部/全局å�˜é‡�填充动æ€�分é…�的内å˜é£�险å�˜é‡�大å°�ä¸�足导致溢出指针未åˆ�始化导致崩溃二ã€�代ç �å®�例深度分æ��
å�˜é‡�ç±»å�‹å®šä¹‰ç¤ºä¾‹// 情况1resistance是普通å�˜é‡�uint32_tresistance;// 4å—节å�˜é‡�// 情况2resistance是指针uint32_t*resistance;// 指å�‘uint32_t的指针
æ£ç¡®ç”¨æ³•示例// 示例1使用æ“�作符resistance是å�˜é‡�uint32_tresistance;// 声æ˜�一个4å—节å�˜é‡�memcpy(resistance,usRegHoldingBuf[res_reg],
;// æ£ç¡®å°†4å—节数æ�®å¤�制到resistanceå�˜é‡�// 示例2ç›´æ�¥ä½¿ç”¨æŒ‡é’ˆresistance是指针uint32_t*resistancemalloc(sizeof(uint32_t));// 分é…�内å˜memcpy(resistance,usRegHoldingBuf[res_reg],
;// æ£ç¡®å°†æ•°æ�®å¤�制到指针指å�‘的内å˜åŒºåŸŸ
错误用法���// 错误示例1��误用为指针uint32_tresistance;memcpy(resistance,usRegHoldingBuf[res_reg],
;// 崩溃将��值当作地�访问resistance包��机值// 错误示例2指针未�始化uint32_t*resistance;// 未�始化memcpy(resistance,usRegHoldingBuf[res_reg],
;// 崩溃访问éš�机内å˜åœ°å�€é‡�指针// 错误示例3大å°�ä¸�匹é…�floatresistance;// 4å—节但类å�‹ä¸�å�Œmemcpy(resistance,usRegHoldingBuf[res_reg],
;// å�±é™©æŒ‰å—节å¤�制å�¯èƒ½ç ´å��浮点表示三ã€�内å˜å¸ƒå±€è¯¦è§£
æ£ç¡®æƒ…况内å˜å¸ƒå±€Modbus寄å˜å™¨æ ˆå†…å˜resistancememcpyæ“�作resistanceå�˜é‡�0x1000usRegHoldingBuf0x
x2003å¤�制4å—节数æ�®
错误情况内å˜å¸ƒå±€Modbus寄å˜å™¨memcpyæ“�ä½œæ ˆå†…å˜å€¼0xDEADBEEFresistanceå�˜é‡�0x1000usRegHoldingBuf0x
x20030xDEADBEEF�试写入四��战应用场景
Modbusæ•°æ�®å¤„ç�†æ�¨è��方案// 安全读å�–32ä½�寄å˜å™¨å€¼uint32_tread_modbus_register(uint16_treg_index){uint32_tvalue;// 检查寄å˜å™¨èŒƒå›´if(reg_indexMAX_REGISTERS-
{return0;// 错误处ç�†}// 使用memcpyé�¿å…�å—节åº�问题memcpy(value,usRegHoldingBuf[reg_index],
;returnntohl(value);// 转æ�¢å—节åº�}
动æ€�æ•°æ�®å¤„ç�†// 创建寄å˜å™¨æ•°æ�®å‰¯æœ¬uint32_t*create_register_copy(uint16_tstart,uint16_tcount){size_tsizecount*sizeof(uint16_t);uint32_t*buffermalloc(size);if(!buffer)returnNULL;// ç›´æ�¥ä½¿ç”¨æŒ‡é’ˆå¤�制数æ�®memcpy(buffer,usRegHoldingBuf[start],size);returnbuffer;}五ã€�常è§�问题解决方案
类�安全�强// 类�安全的memcpy�装templatetypename Tvoidsafe_memcpy(Tdest,constvoid*src){static_assert(!std::is_pointerT::value,Use pointer version for pointer types);memcpy(dest,src,sizeof(T));}// 指针版本�载templatetypename Tvoidsafe_memcpy(T*dest,constvoid*src,size_tcount
{memcpy(dest,src,count*sizeof(T));}// 使用示例uint32_tresistance;safe_memcpy(resistance,usRegHoldingBuf[res_reg]);// 自动æ�¨æ–大å°�uint32_t*pResmalloc(sizeof(uint32_t));safe_memcpy(pRes,usRegHoldingBuf[res_reg]);// 指针版本
å—节åº�处ç�†// 处ç�†å¤§ç«¯åº�å˜å‚¨çš„寄å˜å™¨æ•°æ�®uint32_tread_big_endian(constuint16_t*reg_ptr){uint32_tresult;uint8_t*bytes(uint8_t*)result;// 手动处ç�†å—节åº�bytes[0](reg_ptr[0]
0xFF;bytes[1]reg_ptr[0]0xFF;bytes[2](reg_ptr[1]
0xFF;bytes[3]reg_ptr[1]0xFF;returnresult;}// 使用memcpy的优化版本uint32_tread_big_endian_optimized(constuint16_t*reg_ptr){union{uint32_tvalue;uint16_twords[2];}converter;memcpy(converter.words,reg_ptr,
;return(converter.words[0]
|converter.words[1];}
边界检查强化// 带边界检查的安全�制boolsafe_register_copy(void*dest,size_tdest_size,uint16_treg_index,size_tcopy_size){// 检查�边界if(reg_index(copy_size/
MAX_REGISTERS){returnfalse;}// æ£€æŸ¥ç›®æ ‡å¤§å°�if(dest_sizecopy_size){returnfalse;}memcpy(dest,usRegHoldingBuf[reg_index],copy_size);returntrue;}å…ã€�调试技巧ä¸�验è¯�方法
å†…å˜æ–点设置// GDB调试示例(gdb)presistance// 查看å�˜é‡�地å�€$1(uint32_t*)0x7fffffffdcbc(gdb)watch*(uint32_t*)0x7fffffffdcbc// 设置内å˜å†™å…¥æ–点Hardware watchpoint2:*(uint32_t*)0x7fffffffdcbc(gdb)p resistance// 查看指针值$2(uint32_t*)0x5555555592a0(gdb)watch*(uint32_t*)0x5555555592a0// 设置指针指å�‘内å˜çš„æ–ç‚¹
è¿�行时检测// æ·»åŠ è°ƒè¯•æ£€æŸ¥#defineDEBUG_MEMCPY(dest,src,size)do{\printf(memcpy: %p - %p, size%zu\n,src,dest,size);\if(((uintptr_t)dest0x
||((uintptr_t)src0x
){\printf(ERROR: Invalid memory access!\n);\abort();\}\memcpy(dest,src,size);\}while(
// 使用示例DEBUG_MEMCPY(resistance,usRegHoldingBuf[res_reg],
;七�最佳�践总结
选择指å�—普通å�˜é‡�指针å�˜é‡�数组需è¦�å¤�制数æ�®ç›®æ ‡æ˜¯ä»€ä¹ˆç±»å�‹ä½¿ç”¨ å�–地å�€ç¬¦ç›´æ�¥ä½¿ç”¨æŒ‡é’ˆä½¿ç”¨æ•°ç»„å��ç¡®ä¿�å�˜é‡�大å°�足够确ä¿�指针已åˆ�始化确ä¿�ä¸�越界
黄金法则地å�€æ“�作符规则对普通å�˜é‡�使用对指针å�˜é‡�ç›´æ�¥ä½¿ç”¨å¯¹æ•°ç»„使用数组å��ç‰æ•ˆäº�指针安全检查清å�•if(使用指针){ç¡®ä¿�指针已åˆ�始化();ç¡®ä¿�指针指å�‘çš„å†…å˜æœ‰æ•ˆ();}else{ç¡®ä¿�ç›®æ ‡å�˜é‡�大å°�足够();}ç¡®ä¿�æº�æ•°æ�®å�¯è®¿é—®();ç¡®ä¿�å¤�制大å°�æ£ç¡®();防御性编程// 安全å¤�制模æ�¿voidsafe_register_copy(void*dest,uint16_t*src,size_tsize){assert(dest!NULL);assert(src!NULL);assert((srcusRegHoldingBuf)(srcsize/2usRegHoldingBufMAX_REGISTERS));memcpy(dest,src,size);}
最终结论在您的代ç �ä¸memcpy(resistance,usRegHoldingBuf[res_reg],
;这是æ£ç¡®ç”¨æ³•å‰�æ��是resistance是uint32_t或其它4å—节类å�‹çš„å�˜é‡�res_reg在寄å˜å™¨æ•°ç»„的有效范围内而memcpy(resistance,usRegHoldingBuf[res_reg],
;这需è¦�resistance是指å�‘足够内å˜çš„æŒ‡é’ˆæŒ‡é’ˆå·²æ£ç¡®åˆ�始化如resistance malloc(
;关键记忆点resistance→ 我è¦�修改resistanceå�˜é‡�本身resistance→ 我è¦�修改resistance指å�‘çš„å†…å®¹é€‰é”™ç›®æ ‡åœ°å�€ä¼šå¯¼è‡´ä¸¥é‡�内å˜é”™è¯¯
十九岁免费观看电视剧胖胖的-十九岁免费观看电视剧胖胖的应用