c - 子函数中的指针和赋值

标签 c struct

我有一个小程序,它创建了一个带有一些变量的 semver struct:

typedef struct {
    unsigned major;
    unsigned minor;
    unsigned patch;
    char * note;
    char * tag;
} semver;

然后,我想创建一个函数,它创建一个 semver struct 并将其返回给调用者。基本上,一个工厂。

该工厂将调用初始化函数来设置 semver struct 的默认值:

void init_semver(semver * s) {
    s->major = 0;
    s->minor = 0;
    s->patch = 0;

    s->note = "alpha";

    generate_semver(s->tag, s);
}

最重要的是,我想要一个函数来生成完整的 semver 标签的字符串。

void generate_semver(char * tag, semver * s) {
    sprintf( tag, "v%d.%d.%d-%s",
        s->major, s->minor, s->patch, s->note);
}

我的问题似乎出在这个函数上。我试过返回一个字符串,但是听说 malloc 一些空间是不好的,除非你稍后明确地 free ;) 为了避免这个问题,我决定尝试将字符串传递给函数以在没有返回值的情况下在函数内更改它。我正在尝试松散地遵循 DI 实践之类的东西,尽管我真的很想分离这些函数的关注点并让 generate_semver 函数返回一个我可以像这样使用的字符串:

char * generate_semver(semver * s) {
    char * full_semver;
    sprintf( full_semver, "v%d.%d.%d-%s",
        s->major, s->minor, s->patch, s->note);
    return full_semver; // I know this won't work because it is defined in the local stack and not outside.
}

semver->tag = generate_semver(semver);

我该怎么做?

最佳答案

My problem appears to lie in this function. I have tried returning a string, but have heard that mallocing some space is bad unless you explicitly free it later.

需要显式释放动态分配的内存以避免内存泄漏。但是,这不一定是最终用户需要直接执行的任务:API 通常会提供处理此问题的功能。

在您的情况下,您应该提供一个deinit_semver 函数来清理init_semver 动态分配的内存。这两个函数的行为类似于构造函数和析构函数; init_semver 不是 工厂函数,因为它期望分配 semver struct,而不是在内部分配它.

这是一种实现方式:

void init_semver(semver * s, int major, int minor, int pathc, const char * note) {
    s->major = major;
    s->minor = minor;
    s->patch = pathc;

    size_t len = strlen(note);
    s->note = malloc(len+1);
    strcpy(s->note, note);
    s->tag = malloc(40 + len);
    sprintf(s->tag, "v%d.%d.%d-%s", major, minor, patch, note);
}
void deinit_semver(semver *s) {
    free(s->note);
    free(s->tag);
}

请注意上面的变化:此代码没有为 struct semver 的组件使用固定值,而是将值作为参数。此外,代码将 note 复制到动态分配的缓冲区中,而不是直接指向它。

deinit 函数通过free 清理动态分配的两个字段。

关于c - 子函数中的指针和赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23551270/

相关文章:

c - 显示来自正在传递的 Struct 的数据

c - 结构内部的动态矩阵,C 编程

ios - 尝试在indexpath.row处执行 "swipe left to delete "时出现UITableView SIGBRT错误

c - pthread_join 处的段错误

c - 斯普林特夫 : pad with '\0' character instead of space

c - 回文测试

c - UDP 套接字 (DGRAM) 绑定(bind)/发送错误

C 风格的结构声明

arrays - 初始化从指针目标类型中丢弃 ‘const’ 限定符

c - C 中的多个 Fork 示例