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

C语言嵌套结构体指针访问数组输出异常值原因排查

异常根因

你代码里的异常是悬空指针访问已回收栈内存导致的未定义行为:

  1. assign_arr函数中定义的int arr[3]是栈上分配的局部变量,生命周期仅在assign_arr函数执行期间有效。函数返回后,这块栈内存就会被系统回收,可被后续的函数调用、栈帧操作任意覆写。你把这个局部数组的地址赋值给X->arr,本质是让结构体持有了一个指向无效内存的野指针,这类访问属于C语言标准定义的未定义行为,程序输出任何值、直接崩溃都是可能的,不存在确定性结果。
  2. 前两次循环能正常输出0、1、2只是巧合:这两段打印逻辑都在assign_arr返回后、其他函数调用前执行,原先存arr的栈内存还没被新操作覆写,所以暂时能读到之前写入的正确值,这不代表代码逻辑合法。
  3. 调用my_func时,程序会为该函数创建新的栈帧,原先存arr[0]的栈位置被my_func的栈数据(参数、局部变量、返回地址等)覆写,所以读到了随机垃圾值32765;剩余两个数组元素所在的内存暂时没被覆盖,所以还能输出1、2,只要后续再有栈操作,这两个值也会变成乱码。
修复方案

你的需求是存储运行时确定长度的动态数组,应该使用堆内存分配实现,不要绑定栈上局部变量:

  • 引入标准库头文件<stdlib.h>,在assign_arr中用malloc申请堆内存存储数组,堆内存生命周期由开发者手动控制,不会随函数返回自动回收。
    修复后的assign_arr实现如下:
#include <stdlib.h>

void assign_arr(struct arr_wrapper* X, int arr_len){
    // arr_len可作为参数运行时传入,适配动态长度需求
    int* arr = (int*)malloc(arr_len * sizeof(int));
    for (int i = 0; i < arr_len; i++){
        arr[i] = i;
    }
    X->arr = arr;
    return;
}
  • 注意事项:结构体使用完后,必须手动调用free(arr_wrapper_obj.arr)释放申请的堆内存,避免内存泄漏。
  • 不推荐用static修饰局部数组的方案规避问题:静态数组全局唯一,多次调用assign_arr会覆盖同一块内存,无法适配多实例的动态数组场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 20:15:37