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

C语言结构体动态内存分配问题:同一工人无法分配多个项目的函数修复

C语言结构体动态内存分配问题:同一工人无法分配多个项目的函数修复

我来帮你看看这个问题哈,你的addWorkerToProject函数现在没法给同一个工人添加多个项目,核心是动态内存分配的逻辑出了几个关键问题,咱们一步步拆解修复:

先说说原代码里的几个明显问题

  • 每次调用都覆盖了之前的项目数组指针:原代码里每次调用都直接给worker->projects用malloc分配新内存,这会把之前存储的项目数组指针直接覆盖掉,之前加的项目自然就丢了,第二次调用肯定看不到第一个项目。
  • 内存分配的大小完全错误:malloc(sizeof (strlen(project)+1))这个写法完全不对,worker->projects是Project**类型的指针数组,每个元素是一个Project*指针,所以分配的大小应该是指针的大小 × 数组的长度,而不是字符串长度相关的数值。
  • 结构体定义不完整:你的struct Worker和struct Project定义缺少大括号和分号,而且没有typedef的话,每次声明变量都要写struct,不太方便。
  • 没有正确处理新项目的存储:原代码里直接给worker->projects[worker->projectCount]->name赋值,这里worker->projects[worker->projectCount]是个未初始化的指针,直接访问会导致野指针错误,要么直接存储传入的Project*指针(前提是这个项目对象不会被提前释放),要么为新的Project分配内存并拷贝数据。

修复后的完整代码示例

先把结构体定义补全,再修复addWorkerToProject函数:

// 先提前声明结构体,解决互相引用的问题
struct Project;

typedef struct Worker {
    char *name;
    struct Project **projects; // 这里用struct Project**因为提前声明了
    int projectCount;
} Worker;

typedef struct Project {
    char *name;
    Worker **workers;
    int workerCount;
    // 假设FeatureNode是已经定义好的结构体
    struct FeatureNode *features;
} Project;

void addWorkerToProject(Worker *worker, Project *project) {
    // 1. 先扩容项目数组:如果是第一次添加,分配1个指针的空间;否则扩容为当前数量+1
    Project **tempProjects = realloc(worker->projects, sizeof(Project*) * (worker->projectCount + 1));
    if (tempProjects == NULL) {
        // 内存分配失败的处理,比如打印错误后返回
        perror("Failed to realloc projects");
        return;
    }
    worker->projects = tempProjects;

    // 2. 将传入的项目指针存入数组的新位置
    // 这里直接存储project指针,前提是project对象的生命周期比worker长,不会提前被释放
    worker->projects[worker->projectCount] = project;
    // 如果需要拷贝项目的name而不是共享指针,可以这样做(可选):
    // worker->projects[worker->projectCount] = malloc(sizeof(Project));
    // if (worker->projects[worker->projectCount] == NULL) {
    //     perror("Failed to malloc Project");
    //     return;
    // }
    // worker->projects[worker->projectCount]->name = strdup(project->name);
    // worker->projects[worker->projectCount]->workers = NULL;
    // worker->projects[worker->projectCount]->workerCount = 0;
    // worker->projects[worker->projectCount]->features = NULL;

    // 3. 项目计数加1
    worker->projectCount++;
}

关键修复点的解释

  1. 用realloc扩容数组:realloc可以帮我们把原来的数组内存扩容到新的大小,同时保留原来的数据,这就解决了每次覆盖之前项目的问题。第一次调用时worker->projects是NULL,realloc会等价于malloc,分配新的内存。
  2. 正确计算内存大小:sizeof(Project*) * (worker->projectCount + 1),这里sizeof(Project*)是单个项目指针的大小,乘以新的数组长度(当前数量+1),确保有足够的空间存新的项目指针。
  3. 内存分配失败的检查:一定要检查realloc和malloc的返回值,如果是NULL说明内存分配失败,要做错误处理,避免程序崩溃。
  4. 正确存储项目指针:直接把传入的project指针存入数组,这样就可以直接访问项目的name了。如果你不想共享原项目对象,而是要拷贝一份,可以用注释里的方式,用malloc分配新的Project结构体,再用strdup拷贝字符串(strdup内部会调用malloc和strcpy)。

测试示例的用法

比如你要给Sean添加两个项目,可以这样写:

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

// 上面的结构体和函数定义放在这里

int main() {
    // 创建工人Sean
    Worker *sean = malloc(sizeof(Worker));
    sean->name = strdup("Sean");
    sean->projects = NULL;
    sean->projectCount = 0;

    // 创建两个项目
    Project *firstProject = malloc(sizeof(Project));
    firstProject->name = strdup("first");
    firstProject->workers = NULL;
    firstProject->workerCount = 0;
    firstProject->features = NULL;

    Project *secondProject = malloc(sizeof(Project));
    secondProject->name = strdup("second");
    secondProject->workers = NULL;
    secondProject->workerCount = 0;
    secondProject->features = NULL;

    // 添加项目到Sean
    addWorkerToProject(sean, firstProject);
    addWorkerToProject(sean, secondProject);

    // 打印测试
    for (int i = 0; i < sean->projectCount; i++) {
        printf("Sean's project %d: %s\n", i+1, sean->projects[i]->name);
    }

    // 记得释放内存,避免内存泄漏
    free(sean->name);
    free(sean->projects);
    free(sean);

    free(firstProject->name);
    free(firstProject);
    free(secondProject->name);
    free(secondProject);

    return 0;
}

运行这个程序,就能看到Sean的两个项目都被正确打印出来啦。

备注:内容来源于stack exchange,提问作者strtrs

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.17 11:19:32