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

Valgrind提示memcpy Invalid write of size 8错误,通用栈实现故障求助

故障根因

问题出在指针运算的步长错误:
你定义的stack->value是uintptr_t *类型,C语言中指针加法的偏移量默认以指针指向的元素大小为单位:比如64位系统下uintptr_t占8字节,stack->value + N等价于内存地址偏移N * 8字节,而不是你预期的N字节。
你在计算第stack->count个元素的起始地址时,直接用stack->value + stack->size * stack->count,相当于实际偏移量是stack->size * stack->count * sizeof(uintptr_t),远大于实际申请的内存范围,所以触发越界写入,Valgrind才会报Invalid write错误。stack_pop函数里也存在完全相同的地址计算错误。

修复方案

只需要把做地址偏移的指针先强转为单字节步长的char *类型即可:

// stack_push 中报错的memcpy行修改为
memcpy((char*)stack->value + stack->size * stack->count, value, stack->size);

// stack_pop 中对应的memcpy行同步修改为
memcpy(value, (char*)stack->value + stack->size * stack->count, stack->size);

修改后重新编译运行,Valgrind的越界报错就会消失。

代码优化建议

  • 接口设计优化:将入栈参数uintptr_t *value改为const void *value,出栈参数改为void *value,不需要用户强制转换指针类型,更符合通用容器的使用习惯,减少误用概率。
  • 内存管理优化:value成员可以直接定义为char *类型,内部统一用单字节指针管理内存,避免每次做地址偏移都要强制转换。
  • 缩容逻辑优化:当前pop时只要低于batch边界就会触发realloc,容易出现push到边界又pop导致的频繁内存申请释放,可以调整为仅当已使用容量不足已分配容量的1/2时再执行缩容,降低性能开销。
  • 补充销毁接口:新增stack_destroy函数,主动释放value指向的内存,避免内存泄漏。
  • 参数校验补充:可以补充运行时校验,避免传入的size为0等非法参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 00:15:10