C节点-如何不覆盖分配的内存空间,而是创建新的内存空间(家庭作业问题)

C节点-如何不覆盖分配的内存空间,而是创建新的内存空间(家庭作业问题),c,arrays,memory,allocation,C,Arrays,Memory,Allocation,公司结构定义如下: 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) re

公司结构定义如下:

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最终包含指向所有公司的指针)

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


如何更正它,使其不会覆盖,而是始终分配新空间?

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

newNode->company_name = strdup(company_name);
strdup
动态复制传递给它的字符串。别忘了释放它

这是一个常见错误,因为
公司名称
包含一些数据的地址。如果使用了相同的地址,并且其中的数据发生了更改,则最终会得到不同的结果,因此需要对其进行复制。

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

newNode->company_name = strdup(company_name);

不要忘记在调用
make\u company\u node
函数之前先释放它。

如果您知道公司名称的长度,我会将函数更改为接受该长度(否则使用strlen)


我更喜欢使用
malloc
strcpy
,而不是
strdup
,因为
strdup
不是由标准定义的(虽然它是由POSIX定义的),如果如pmg所述,您事先知道字符串的长度,或者如果您可以设置已知的最大字符数,则更愿意将公司名称定义为静态数组:


字符公司名称[最大长度];


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

您的代码看起来正常,您确定这不是由于没有正确索引Companyion的变量而导致的吗?我现在明白了,它确实解决了问题。但是我怎么才能释放它呢?免费(公司名称)?这就产生了一个巨大的“内存映射”输出,我真的不需要…为了清理,你需要迭代你的数组并执行:
free(companyion->company\u arr[I]->company\u name)+1,用于说明最明显的方法,使程序实现OP最初想要的功能。哦欢迎使用此方法,我必须迭代并释放内存吗?是的,与使用
strdup
相同。否则,你最好的选择是
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;
}