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

C语言结构体数组双指针内存分配异常:r及r[0]变为0x0的问题

问题分析与解决方案

嘿,我来帮你捋捋这个问题~你的代码核心bug出在对双指针形参的理解偏差:当你在func函数里直接给r赋值malloc的结果时,你修改的只是函数内部的局部变量副本,外部传入的实参根本不会同步这个变化。所以函数退出后,外部的r还是原来的初始值(大概率是0x0),而你在函数里分配的内存还会变成没人管的“孤儿”,造成内存泄漏。

修正后的完整代码示例

先给你改好的可运行代码,再一步步解释关键逻辑:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>

struct R {
    int x;
    int y;
    char * z;
};

void func(struct R **r) {
    // 1. 给外部的指针数组分配内存:*r指向外部传入的struct R**变量
    *r = malloc(4 * sizeof(struct R *));
    if (*r == NULL) {
        perror("Failed to allocate pointer array");
        return;
    }

    // 2. 给数组第一个元素分配结构体内存
    (*r)[0] = malloc(sizeof(struct R));
    if ((*r)[0] == NULL) {
        perror("Failed to allocate struct R");
        free(*r); // 先释放已分配的数组,避免内存泄漏
        *r = NULL;
        return;
    }

    // 3. 给结构体成员赋值
    (*r)[0]->x = 1;
    (*r)[0]->y = 2;
    // 用strdup分配字符串内存(内部已完成malloc+strcpy),也可以手动malloc+strcpy
    (*r)[0]->z = strdup("Hello World");
    if ((*r)[0]->z == NULL) {
        perror("Failed to allocate string");
        free((*r)[0]);
        free(*r);
        *r = NULL;
        return;
    }
}

int main() {
    struct R **my_r = NULL;
    func(&my_r);

    // 验证结果
    if (my_r != NULL && my_r[0] != NULL) {
        printf("x: %d, y: %d, z: %s\n", my_r[0]->x, my_r[0]->y, my_r[0]->z);

        // 4. 逆向释放内存,避免泄漏
        free(my_r[0]->z);
        free(my_r[0]);
        free(my_r);
        my_r = NULL;
    }
    return 0;
}

关键修正点说明

  • 操作*r而非r:r是函数的形参,它指向外部的struct R**变量,只有修改*r(也就是外部真正的指针数组变量),才能让外部获取到分配的内存地址。
  • 必须检查malloc返回值:任何动态内存分配都可能失败并返回NULL,不检查的话会导致空指针访问崩溃。
  • 内存释放要顺序正确:先释放结构体内部的字符串,再释放结构体本身,最后释放指针数组,顺序反了会触发野指针问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:09:13