【问题标题】:C nodes - how to not overwrite the allocated memory space but create new one (homework issue)C节点 - 如何不覆盖分配的内存空间但创建新的(作业问题)
【发布时间】:2010-12-11 17:10:26
【问题描述】:

公司结构定义如下:

typedef struct company {
 char* company_name;
 int employee_counter;
} company;

我使用这个函数来创建一个新的公司节点:

company *make_company_node(char* company_name, int employee_counter) {
 company *newNode = (company*) malloc(sizeof(company));
 if(!newNode) return NULL; 

 newNode->company_name = company_name;
 newNode->employee_counter = employee_counter;

 return newNode;
}

然后我从输入中得到一些公司名称,为每个创建公司节点:

companyUnion->company_arr[i] = make_company_node(company_name, 0);

(company_arr 最终包含指向所有公司的指针)。

问题是我似乎总是覆盖最初分配的内存空间,因此最后我得到一个数组,其单元格都指向最后一家公司(提交的姓氏)。

我怎样才能纠正它,使它不会被覆盖而是总是分配新的空间?

【问题讨论】:

  • 你的代码看起来不错,你确定它没有发生是因为没有正确索引 companyUnion 的变量吗?

标签: c arrays memory allocation


【解决方案1】:

如果您在调用 make_company_node 函数之前知道 company_name 的长度,我会更改函数以接受该长度(否则使用 strlen)。

company *make_company_node(char *company_name, size_t cn_len, int employee_counter) {
    company *newNode = malloc(sizeof *newNode);
    if (newNode) {
        newNode->company_name = malloc(cn_len + 1);
        if (newNode->company_name) {
            strcpy(newNode->company_name, company_name);
            newNode->employee_counter = employee_counter;
        } else {
            free(newNode);
            newNode = NULL;
        }
    }
    return newNode;
}

我更喜欢使用mallocstrcpy,而不是strdup,因为strdup 不是由标准定义的(虽然它是由POSIX 定义的),并且使用@987654328 没有任何优势@。

【讨论】:

  • 使用这种方法是不是必须迭代和释放内存?
  • 是的,与strdup 相同。否则,你最好的选择是gen's suggestion
【解决方案2】:

如果如 pmg 所述,您事先知道字符串的长度,或者如果您可以设置已知的最大字符数,则最好将 company_name 定义为静态数组:

char company_name[MAX_LENGTH];

这将减少您需要执行的内存管理量,以及您刚刚遇到的潜在错误。

【讨论】:

  • +1 用于说明使程序首先执行 OP 想要的最明显的方法。 哦!欢迎来到 SO
【解决方案3】:

Hrm,看来问题出在company_name 变量上。这是一个指向公司名称实际数据的指针。您如何分配这些数据?你确定这是正确的指针吗?也许你需要这样的东西:

newNode->company_name = strdup(company_name);

strdup 动态地复制您传递给它的字符串。不要忘记释放它。

这是一个常见错误,因为company_name 包含一些数据的地址。如果使用相同的地址,其中的数据发生变化,最终会得到不同的结果,因此您需要对其进行复制。

【讨论】:

  • 我现在明白了,它确实解决了问题。我如何释放它?免费(公司名称); ?这会创建一个我并不真正需要的巨大“内存映射”输出......
  • 要清理你需要遍历你的数组并执行:free(companyUnion->company_arr[i]->company_name);
【解决方案4】:

您需要复制公司名称字符串:

newNode->company_name = strdup(company_name);

之后别忘了free()

【讨论】:

    猜你喜欢
    • 2011-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-06
    • 1970-01-01
    • 2016-08-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多