C语言*(long *)/*(int*)含义及自定义memcpy用char类型原因咨询
问题1:两行类型转换赋值代码的功能
默认add1、add2为void*或其他非匹配类型的指针变量,两行代码的作用分别是:
- Line 1:
*(long *)add1= *(long *)add2;
将add1、add2强制转换为long类型的指针后解引用,把add2指向内存中1个long长度的数据,拷贝到add1指向的内存地址。32位系统下long通常为4字节,64位系统下通常为8字节,即一次拷贝对应长度的连续字节。 - Line 2:
*(int *)add1 = *(int *)add2;
逻辑和Line1一致,仅将指针转换为int*类型,一次拷贝1个int长度的数据,主流平台下int通常为4字节。
注意:如果
add1、add2的地址不满足long/int类型的内存对齐要求,上述代码会触发未定义行为,部分架构下会直接导致程序崩溃。
问题2:内存重叠场景下使用
char*转换拷贝的原因 你贴出的代码片段属于自定义内存拷贝(通常是处理重叠场景的memmove实现)的收尾逻辑,选择char类型做指针转换而非long/int的原因有三点:
- 粒度精确:C标准明确规定
char类型的长度为1字节,转换为char*后每次操作正好读写1字节,不管剩余待拷贝长度是多少都能精确匹配,不会出现多拷/少拷的问题。如果使用long/int,只能处理长度为对应类型字节数整数倍的场景,不足的剩余字节无法处理。 - 无对齐限制:
char类型的内存对齐要求为1,任何内存地址都满足对齐要求,访问不会出错。而long/int有对齐要求,内存重叠场景下src和temp的地址偏移很可能不满足对齐条件,强制转换为对应类型指针访问会触发未定义行为,轻则性能下降,重则程序崩溃。 - 保证重叠拷贝正确性:内存重叠场景下(例如目标地址在源地址后方),需要严格控制拷贝顺序避免未读数据被提前覆盖,逐字节拷贝可以严格保证读写顺序的正确性,大粒度的
long/int拷贝很容易出现数据覆盖的问题。
内容的提问来源于stack exchange,提问作者Adil.Kolenko
相关产品推荐
相关产品推荐

