分配缓冲区空间过大时,除memcpy外还有其他可用的替代方案吗?
解答
你给出的栈上分配+memcpy拷贝的实现,在必须做截断拷贝的场景下已经是效率极高的方案,多数编译器会把memcpy优化为对应平台的最优汇编实现,额外开销极小。针对不同使用场景,还有以下更优的选择:
- 原缓冲区为堆分配场景
如果src是通过malloc/calloc从堆上申请的内存,不需要额外申请缓冲区拷贝,直接调用realloc收缩原有内存块即可:
多数情况下操作系统可以直接修改堆块的元数据完成内存收缩,不需要任何内存拷贝,性能远高于char* src = malloc(100); size_t sz = 20; // 向src写入20字节数据后 char* tmp = realloc(src, sz); if (tmp) { src = tmp; }memcpy方案。 - 仅临时使用截断后数据的场景
比如你提到的网络发送场景,完全不需要额外申请缓冲区拷贝数据,直接把原缓冲区指针、实际使用长度传给对应接口即可:
这种方案完全省掉了内存申请、拷贝的开销,是这类场景的最优解。char src[100]; size_t sz = 20; // 写入数据后直接调用发送接口 send(sock_fd, src, sz, 0); - 必须做栈上数据拷贝的场景
你当前使用的memcpy方案已经是最优的标准实现,手动实现的拷贝逻辑除非针对特定硬件做SIMD指令优化,否则不可能比编译器优化后的memcpy性能更好。
额外注意:你示例中使用的可变长度数组(VLA)是C99引入的特性,在C11标准中改为可选实现,部分编译器(如MSVC)并不支持该特性,如果需要跨平台兼容建议避免使用VLA做缓冲区分配。
内容的提问来源于stack exchange,提问作者Senne Verhaegen
相关产品推荐
相关产品推荐

