C动态分配结构数组及其组件
C dynamically allocate struct array and its components
在 C 中动态分配结构数组及其组件的正确方法是什么?我设法做了一些有用的事情,但我有点怀疑它是否正确。
我有以下代码:
这是我需要动态分配的结构数组:
typedef struct
{
char *wrong;
char *right;
}Dictionary;
这是我需要初始化结构数组时调用的函数:
Dictionary *init_Dictionary(int nr_elem)
{
Dictionary *dict;
dict = malloc(nr_elem*sizeof(Dictionary));
for(int i=0; i<nr_elem; i++)
{
char wrong[101],right[101];
scanf("%s%s",wrong,right);
dict[i].wrong = malloc(strlen(wrong)*sizeof(char));
dict[i].right = malloc(strlen(right)*sizeof(char));
strcpy(dict[i].wrong,wrong);
strcpy(dict[i].right,right);
}
return dict;
}
然后在我的主要功能中,我有这个:
int nr_elem;
scanf("%d",&nr_elem);
Dictionary *dict;
dict = init_Dictionary(nr_elem);
此外,当我完成对结构的处理后,如何释放已用内存?
编辑感谢大家快速而深入的回答!
程序设计不好,应该UI和算法分开。取而代之的是,您应该首先获取用户输入,然后将其存储在 2 个字符串中并将字符串作为参数传递给 init_Dictionary
。
至于分配,几乎是正确的。但是你忘了为空终止符分配space,它应该是:
dict[i].wrong = malloc(strlen(wrong)+1);
dict[i].right = malloc(strlen(right)+1);
乘以 sizeof(char)
没有意义,因为 sizeof(char)
的定义在所有系统上总是 1
。
在生产质量的应用程序中,您必须始终检查每个 malloc
的结果,然后处理错误。
释放内存的方式与分配内存的方式相同,但顺序相反,因为在释放其成员之前需要 dict
本身有效:
for(int i=0; i<nr_elem; i++)
{
free(dict[i].wrong);
free(dict[i].right);
}
free(dict);
根据经验,对 malloc
的每次调用都必须与对 free
.
的调用相匹配
您的实现中存在错误:strlen(s)
不计算终止 0 字符,因此,尽管一个测试可能成功,但这实际上是一个 UB。 strdup
可以为你工作;如果您没有标准库,则在为字符串副本分配内存时只需加 1。甚至更好:计算一次字符串长度,然后使用此值分配足够的字节并使用 memcpy
.
复制内容
否则,您的算法非常有用(前提是字符串对数组确实是您所需要的,没有搜索索引或任何其他结构)。
要释放它,添加一个执行逐元素释放然后释放整个数组的析构函数:
void destroy(Dictionary *dict, size_t nr_elem) {
for(size_t i = 0; i < nr_elem; ++i) {
free(dict[i].wrong);
free(dict[i].right);
}
free(dict);
}
对于每个分配,您需要再分配一个位置以允许在字符串末尾使用 [=12=]
(NULL 终止符)。
dict[i].wrong = malloc(strlen(wrong)*sizeof(char) +1 );
dict[i].right = malloc(strlen(right)*sizeof(char) +1);
要释放,首先需要释放数组中的所有指针right
和wrong
,然后释放主dict
数组。或者,您可以在释放后将指针置空。
Dictionary* freeDict(Dictionary *dict, int nr_elem)
{
for (int i=0; i<nr_elem; i++)
{
free(dict->wrong);
free(dict->right);
dict->wrong = NULL;
dict->right = NULL;
}
free (dict);
dict = NULL;
return dict;
}
//To call.
dict = free(dict, nr_elem);
在 C 中动态分配结构数组及其组件的正确方法是什么?我设法做了一些有用的事情,但我有点怀疑它是否正确。
我有以下代码:
这是我需要动态分配的结构数组:
typedef struct
{
char *wrong;
char *right;
}Dictionary;
这是我需要初始化结构数组时调用的函数:
Dictionary *init_Dictionary(int nr_elem)
{
Dictionary *dict;
dict = malloc(nr_elem*sizeof(Dictionary));
for(int i=0; i<nr_elem; i++)
{
char wrong[101],right[101];
scanf("%s%s",wrong,right);
dict[i].wrong = malloc(strlen(wrong)*sizeof(char));
dict[i].right = malloc(strlen(right)*sizeof(char));
strcpy(dict[i].wrong,wrong);
strcpy(dict[i].right,right);
}
return dict;
}
然后在我的主要功能中,我有这个:
int nr_elem;
scanf("%d",&nr_elem);
Dictionary *dict;
dict = init_Dictionary(nr_elem);
此外,当我完成对结构的处理后,如何释放已用内存?
编辑感谢大家快速而深入的回答!
程序设计不好,应该UI和算法分开。取而代之的是,您应该首先获取用户输入,然后将其存储在 2 个字符串中并将字符串作为参数传递给 init_Dictionary
。
至于分配,几乎是正确的。但是你忘了为空终止符分配space,它应该是:
dict[i].wrong = malloc(strlen(wrong)+1);
dict[i].right = malloc(strlen(right)+1);
乘以 sizeof(char)
没有意义,因为 sizeof(char)
的定义在所有系统上总是 1
。
在生产质量的应用程序中,您必须始终检查每个 malloc
的结果,然后处理错误。
释放内存的方式与分配内存的方式相同,但顺序相反,因为在释放其成员之前需要 dict
本身有效:
for(int i=0; i<nr_elem; i++)
{
free(dict[i].wrong);
free(dict[i].right);
}
free(dict);
根据经验,对 malloc
的每次调用都必须与对 free
.
您的实现中存在错误:strlen(s)
不计算终止 0 字符,因此,尽管一个测试可能成功,但这实际上是一个 UB。 strdup
可以为你工作;如果您没有标准库,则在为字符串副本分配内存时只需加 1。甚至更好:计算一次字符串长度,然后使用此值分配足够的字节并使用 memcpy
.
否则,您的算法非常有用(前提是字符串对数组确实是您所需要的,没有搜索索引或任何其他结构)。
要释放它,添加一个执行逐元素释放然后释放整个数组的析构函数:
void destroy(Dictionary *dict, size_t nr_elem) {
for(size_t i = 0; i < nr_elem; ++i) {
free(dict[i].wrong);
free(dict[i].right);
}
free(dict);
}
对于每个分配,您需要再分配一个位置以允许在字符串末尾使用 [=12=]
(NULL 终止符)。
dict[i].wrong = malloc(strlen(wrong)*sizeof(char) +1 );
dict[i].right = malloc(strlen(right)*sizeof(char) +1);
要释放,首先需要释放数组中的所有指针right
和wrong
,然后释放主dict
数组。或者,您可以在释放后将指针置空。
Dictionary* freeDict(Dictionary *dict, int nr_elem)
{
for (int i=0; i<nr_elem; i++)
{
free(dict->wrong);
free(dict->right);
dict->wrong = NULL;
dict->right = NULL;
}
free (dict);
dict = NULL;
return dict;
}
//To call.
dict = free(dict, nr_elem);