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

C语言VirtualBox Ubuntu虚拟机下动态分配数组内容非预期变更问题

问题根因及修复方案

你遇到的是典型的堆内存缓冲区溢出导致的未定义行为,核心错误出现在动态内存分配行,具体原因如下:

  • 内存分配时大小参数填写错误
    你声明的array是my_obj*类型,用于存储多个my_obj结构体实例,但是calloc的第二个参数错误填写为sizeof(my_obj*)(即指针类型的大小,32位系统下为4字节、64位下为8字节),远小于my_obj结构体本身的实际大小,导致分配的堆内存空间远小于实际需要的容量。array2也存在完全相同的错误。
    后续你在给数组元素赋值时,写入操作直接越界,踩踏了相邻的堆内存区域。第一次打印正常是因为刚写入的内容还没被覆盖,当你填充array2时,越界写入的操作会覆盖array对应内存区域的内容,就出现了无规律的随机值。
  • 其他可能的触发原因
    如果修复上述问题后现象依然存在,可排查以下两点:
    1. 全局变量arr_length/arr_length_2的实际值大于预期,导致循环赋值时超出分配的内存边界
    2. my_obj/my_obj2结构体包含柔性数组成员,直接用sizeof(类型)计算的大小没有包含柔性数组需要的内存空间,同样会导致分配不足

修复代码

将内存分配行改为以下写法即可,推荐第二种写法,避免后续修改类型时重复出现同类错误:

// 写法1:明确指定结构体类型
my_obj* array = calloc(arr_length, sizeof(my_obj));
my_obj2* array2 = calloc(arr_length_2, sizeof(my_obj2));

// 写法2:解引用指针自动获取目标类型大小,更安全
my_obj* array = calloc(arr_length, sizeof(*array));
my_obj2* array2 = calloc(arr_length_2, sizeof(*array2));

注:C语言本身不做内存边界检查,越界访问属于未定义行为,不会触发显式报错,只会出现值篡改、段错误等随机现象,和你使用的虚拟机、Ubuntu系统没有关联。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 14:54:07