You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

同一内存区域的const与非const指针及memmove重叠区域疑问

关于SPI_TransmitReceive函数重叠缓冲区调用的疑问

问题描述

我写了这么一个函数:

void SPI_TransmitReceive(const uint8_t* txbuf, uint8_t* rxbuf, size_t size);

调用的时候把同一个缓冲区同时传给txbuf和rxbuf:

uint8_t mybuf[200];
SPI_TransmitReceive(mybuf, mybuf, 200);

这么做会触发未定义行为吗?

补充说明

假设这个函数的实现是这样的:

void SPI_TransmitReceive(const uint8_t* txbuf, uint8_t* rxbuf, size_t size) {
    std::memmove(rxbuf, txbuf, size);
}

我看到cppreference上说memmove如果遇到内存区域重叠会导致未定义行为,这是不是笔误?


解答

首先要纠正一个关键误解:你搞反了memmove和memcpy的特性。

  • memcpy才是当源和目标内存区域重叠时行为未定义;
  • memmove恰恰是专门为处理重叠内存区域设计的,它会先把需要复制的数据临时存起来,再写入目标地址,所以哪怕源和目标完全重叠,也能保证操作安全,不存在未定义行为。你看到的cppreference描述大概率是把两个函数搞混了,或者是你看错了函数名。

再回到你的函数调用问题:

  1. 如果是你补充的这种用memmove实现的函数:把同一个缓冲区传进去完全没问题,不会触发未定义行为,最终缓冲区内容和原内容一致(因为自己复制自己)。
  2. 如果这个函数是实际操作SPI硬件的收发逻辑(这才是这类函数的真实用途):SPI是同步收发,每发送一个字节的同时会接收一个字节。此时用同一个缓冲区的话,每一步接收的新字节会覆盖掉还没发送的原字节,最终缓冲区的内容会是混乱的,但这属于逻辑错误,不是C标准定义的未定义行为。

内容的提问来源于stack exchange,提问作者Xeenych Xeenych

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 06:25:25