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

void*数组内存分配异常:越界写入未崩溃与首元素占用疑问

void** arr;

arr = realloc(NULL, 1); // 分配1字节
arr[0] = (void *)1;     // 写入8字节指针

arr = realloc(arr, 2); // 分配2字节
arr[1] = (void *)2;    // 再写入8字节指针

arr = realloc(arr, 4); // 分配4字节
arr[2] = (void *)3;    // 再写入8字节指针
arr[3] = (void *)4;    // 再写入8字节指针

// 报错
arr = realloc(arr, 8); // 抛出realloc(): invalid next size错误,推测是写坏了malloc元数据
问题解答

1. 越界写入未触发段错误,直到realloc才报错的原因

段错误只会在进程访问不属于自身地址空间的内存页时触发。你用realloc分配的内存位于堆区,堆中malloc管理的内存块周围,通常还有属于当前进程的空闲内存块或malloc内部维护的元数据区域(比如记录块大小、前后块指针的信息)——这些区域都属于进程合法地址空间,所以越界写入只是破坏了未授权的合法内存,不会触发段错误。

直到最后一次调用realloc时,它需要读取malloc元数据来处理内存块的扩容或迁移,此时发现元数据已被越界写入破坏(比如块大小记录被篡改),就会抛出realloc(): invalid next size错误,这是malloc检测到内部数据结构损坏后的标准报错。

2. arr[0]赋值仅占4B,其他指针赋值占8B的差异原因

在64位系统中,void*指针大小固定为8字节,所有arr[n] = (void*)x的操作本质都会写入8字节数据,差异来自调试器的显示逻辑:

  • 第一次仅分配1字节,调试器可能只高亮进程“合法拥有”的1字节,但实际写入的8字节覆盖了后续7字节越界区域。如果这些越界区域原本是0(堆初始化或空闲块默认值),写入(void*)1(内存中为0x0000000000000001)时,只有低4字节0x00000001有变化,高4字节原本就是0,调试器可能只展示有变化的部分,看起来像仅占用4B。
  • 后续arr[1]、arr[2]等赋值时,对应内存区域原本非0,写入8字节指针后所有字节都有变化,调试器完整展示了8字节修改,所以呈现为8B占用。

也可能是调试器对“已分配内存”和“越界内存”的显示区分导致——仅标记已分配部分,但实际写入操作已覆盖更多字节。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 14:45:35