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

含指针成员的结构体指针的动态内存分配问题

解决结构体指针二维数组的内存分配与访问违规问题

我看了你的代码,出现“Access violation writing location”错误,主要是踩了几个动态内存分配和访问的典型坑,下面给你逐一拆解并修复:

核心错误点分析

1. 未为结构体实例分配内存

你只给person(结构体指针数组)分配了内存,但数组里的每个person[i]都是未初始化的野指针,直接去访问person[i]->name这类成员,相当于操作随机内存,必然触发访问违规。

2. malloc的大小计算错误

你写的:

person = (detailsOf **)malloc(maxSize * sizeof(detailsOf **));

这里sizeof(detailsOf **)是“指针的指针”的大小,而我们需要的是每个数组元素(detailsOf*类型)的大小,应该改成sizeof(detailsOf *)。

3. scanf参数传递错误

在inputValue函数里,读取birthdate和phoneNum的元素时,你传的是person[i]->birthdate[j](一个int值),但scanf需要的是内存地址,应该传&person[i]->birthdate[j](或者直接用person[i]->birthdate + j,因为数组名本身是指针)。

4. 内存释放逻辑错误

  • 你试图循环释放name[j]、phoneNum[j]这类单个元素,但这些都是calloc分配的连续数组内存,只需要直接释放对应的指针(比如free(person[i]->name))即可,循环释放单个元素会导致未定义行为。
  • 释放顺序要注意:先释放结构体内部的成员指针,再释放结构体本身,最后释放结构体指针数组。

修正后的完整代码

#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <stdio.h>
#include<string.h>
#include <stdlib.h>

typedef struct template{
    char *name;
    int *birthdate;
    int *phoneNum;
} detailsOf;

void inputValue(detailsOf **person, int maxSize);

int main() {
    detailsOf **person;
    int maxSize = 0;
    printf("Max:");
    scanf("%d", &maxSize);

    // 第一步:分配结构体指针数组的内存
    person = malloc(maxSize * sizeof(detailsOf *));
    if (person == NULL) {
        printf("Failed to allocate array\n");
        exit(EXIT_FAILURE);
    }

    // 第二步:为每个结构体实例分配内存,并初始化成员指针
    for (int i = 0; i < maxSize; i++) {
        // 先给结构体本身分配内存
        person[i] = malloc(sizeof(detailsOf));
        if (person[i] == NULL) {
            printf("Failed to allocate struct\n");
            exit(EXIT_FAILURE);
        }
        // 再给结构体的成员指针分配内存
        person[i]->name = calloc(21, sizeof(char));
        person[i]->birthdate = calloc(8, sizeof(int));
        person[i]->phoneNum = calloc(16, sizeof(int));
    }

    inputValue(person, maxSize);

    // 第三步:正确释放内存
    for (int i = 0; i < maxSize; i++) {
        // 先释放结构体内部的成员指针
        free(person[i]->name);
        free(person[i]->birthdate);
        free(person[i]->phoneNum);
        // 再释放结构体本身
        free(person[i]);
    }
    // 最后释放结构体指针数组
    free(person);

    return 0;
}

void inputValue(detailsOf **person, int maxSize) {
    for (int i = 0; i < maxSize; i++) {
        printf("Name of %d: ", i + 1);
        scanf("%s", person[i]->name); // name是char*,直接传指针即可

        printf("Birthdate of %d (8 digits):\n", i + 1);
        for (int j = 0; j < 8; j++) {
            printf("Digit %d: ", j + 1);
            scanf("%d", &person[i]->birthdate[j]); // 传int变量的地址
        }

        printf("Phone number of %d (16 digits):\n", i + 1);
        for (int k = 0; k < 16; k++) {
            printf("Digit %d: ", k + 1);
            scanf("%d", &person[i]->phoneNum[k]); // 传int变量的地址
        }
    }
    printf("SUCCESS\n");
}

关键修复说明

  1. 分层分配内存:先分配结构体指针数组,再逐个分配结构体实例,最后分配结构体内部的成员指针,确保每一层指针都指向有效的内存。
  2. 修正scanf参数:读取int类型时必须传递变量的地址,否则scanf无法修改变量的值,还会导致内存访问错误。
  3. 正确释放内存:按照“反向分配顺序”释放内存,避免出现悬空指针或重复释放的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:02:22