如何正确 return 一个结构数组(在此代码战示例中)?
How to return an array of structs properly (in this codewars example)?
我已经在这个特殊的代码战练习上停留了一段时间了。不是因为拼图本身很难(不,我只用了几分钟就能打印出正确的结果),而是因为我似乎无法弄清楚如何 return 结果。
我应该 return 一个结构数组。我知道我不能只是静态分配它然后 return 它。我必须动态分配内存和 return 指针。我这样做(n-m 是我可能需要的最大结构数量 return):
Pair* res = malloc((n-m)*sizeof(Pair));
然后我按如下方式赋值:
res[t].first = i;
res[t].snd = sum;
然后return数组:
return res;
如果我在 return 打印之前打印整个数组,它就会显示为已填满。但是 codewars 系统说我 returned 了一个空数组?
我能够通过向 return 地址添加一个符号来解决这个问题。通过这样做,它 return 第一个结构正确(我能够通过添加手动检查来解决这个问题),但第二个结构将是垃圾数据。
有人知道我可能做错了什么吗?
这是完整的函数(删除了计算,因为它们与问题无关,也可能会破坏在解决问题时偶然发现此问题的其他人的困惑):
Pair** listSquared(long long m, long long n, int* length) {
Pair* res = malloc((n-m)*sizeof(Pair));
int t = 0;
long long sum = 0;
for(int i = m; i<=n; i++)
{
if(sum = isSumSquare(i))
{
res[t].first = i;
res[t].snd = sum;
t++;
}
}
*length = t;
return res;
}
还有一件事:我确实注意到 return 类型是 Pair**。我猜这是我做错了什么,但我也尝试制作 res Pair** 的数据类型(然后在分配时将 . 替换为 ->),and/or 采用 sizeof(Pair*)而不仅仅是配对。我尝试了数不清的组合,但仍然没有得到任何有效的方法。我觉得我在这里缺少一些关于指针的基本知识......
谁能告诉我我做错了什么?
编辑:根据 Gilles 的要求,确切的问题陈述:https://i.imgur.com/gFdDJlz.png
如上所述,type
控制着一切。你得到了一个带有 Pair **listSquared (...)
的函数原型。该函数必须 return 键入 Pair**
(例如 指针到指针 以键入 Pair
)
返回一个指向指针的指针到动态分配的对象需要先在listSquared
中声明Pair**
类型的对象并分配指针的数量必需,例如
Pair **res = malloc ((n-m) * sizeof *res);
(注意: 如果您总是使用解除引用的指针设置 typesize,sizeof *res
而不是 sizeof (Pair*)
, 不可能出错)
然后在你填充每个struct Pair
的循环中的函数中,你首先需要为每个结构分配一个内存块,并将该块的起始地址分配给你的指针,例如
res[t] = malloc (sizeof *res[t]);
在每种情况下,对于每次分配,在尝试使用指针之前,您需要验证分配成功或内存块。例如:
if (!res) { /* validate EVERY allocation */
perror ("malloc-res");
*length = 0; /* set length zero */
return NULL; /* return NULL indicating failure */
}
并且在为 res[t]
分配失败的情况下,您需要 free()
每个先前分配的结构 和 return 之前的指针避免造成内存泄漏,例如
if(sum = isSumSquare(i))
{ /* allocate for res[t] and validate, free all on failure */
if (!(res[t] = malloc (sizeof *res[t]))) {
perror ("malloc-res[t]");
while (t--) /* free previously allocated structs */
free (res[t]);
free (res); /* free pointers */
*length = 0; /* set length zero */
return NULL; /* return NULL indicating failure */
}
res[t].first = i;
res[t].snd = sum;
t++;
}
根据我对你需要做什么的最佳理解,你可以把它和类似的东西放在一起:
Pair **listSquared (long long m, long long n, int *length)
{
Pair **res = malloc ((n-m) * sizeof *res);
int t = 0;
long long sum = 0;
if (!res) { /* validate EVERY allocation */
perror ("malloc-res");
*length = 0; /* set length zero */
return NULL; /* return NULL indicating failure */
}
for(int i = m; i<=n; i++)
{
if(sum = isSumSquare(i))
{ /* allocate for res[t] and validate, free all on failure */
if (!(res[t] = malloc (sizeof *res[t]))) {
perror ("malloc-res[t]");
while (t--) /* free previously allocated structs */
free (res[t]);
free (res); /* free pointers */
*length = 0; /* set length zero */
return NULL; /* return NULL indicating failure */
}
res[t].first = i;
res[t].snd = sum;
t++;
}
}
*length = t;
return res;
}
在分配失败的情况下,您的函数 returns NULL
并释放了它在失败点之前分配的所有内存,消除了所有潜在的内存泄漏。
很高兴您能正常工作并提交了您的代码。如果您对上述推理有任何疑问,请发表评论,我很乐意进一步提供帮助。
我已经在这个特殊的代码战练习上停留了一段时间了。不是因为拼图本身很难(不,我只用了几分钟就能打印出正确的结果),而是因为我似乎无法弄清楚如何 return 结果。
我应该 return 一个结构数组。我知道我不能只是静态分配它然后 return 它。我必须动态分配内存和 return 指针。我这样做(n-m 是我可能需要的最大结构数量 return):
Pair* res = malloc((n-m)*sizeof(Pair));
然后我按如下方式赋值:
res[t].first = i;
res[t].snd = sum;
然后return数组:
return res;
如果我在 return 打印之前打印整个数组,它就会显示为已填满。但是 codewars 系统说我 returned 了一个空数组? 我能够通过向 return 地址添加一个符号来解决这个问题。通过这样做,它 return 第一个结构正确(我能够通过添加手动检查来解决这个问题),但第二个结构将是垃圾数据。
有人知道我可能做错了什么吗?
这是完整的函数(删除了计算,因为它们与问题无关,也可能会破坏在解决问题时偶然发现此问题的其他人的困惑):
Pair** listSquared(long long m, long long n, int* length) {
Pair* res = malloc((n-m)*sizeof(Pair));
int t = 0;
long long sum = 0;
for(int i = m; i<=n; i++)
{
if(sum = isSumSquare(i))
{
res[t].first = i;
res[t].snd = sum;
t++;
}
}
*length = t;
return res;
}
还有一件事:我确实注意到 return 类型是 Pair**。我猜这是我做错了什么,但我也尝试制作 res Pair** 的数据类型(然后在分配时将 . 替换为 ->),and/or 采用 sizeof(Pair*)而不仅仅是配对。我尝试了数不清的组合,但仍然没有得到任何有效的方法。我觉得我在这里缺少一些关于指针的基本知识......
谁能告诉我我做错了什么?
编辑:根据 Gilles 的要求,确切的问题陈述:https://i.imgur.com/gFdDJlz.png
如上所述,type
控制着一切。你得到了一个带有 Pair **listSquared (...)
的函数原型。该函数必须 return 键入 Pair**
(例如 指针到指针 以键入 Pair
)
返回一个指向指针的指针到动态分配的对象需要先在listSquared
中声明Pair**
类型的对象并分配指针的数量必需,例如
Pair **res = malloc ((n-m) * sizeof *res);
(注意: 如果您总是使用解除引用的指针设置 typesize,sizeof *res
而不是 sizeof (Pair*)
, 不可能出错)
然后在你填充每个struct Pair
的循环中的函数中,你首先需要为每个结构分配一个内存块,并将该块的起始地址分配给你的指针,例如
res[t] = malloc (sizeof *res[t]);
在每种情况下,对于每次分配,在尝试使用指针之前,您需要验证分配成功或内存块。例如:
if (!res) { /* validate EVERY allocation */
perror ("malloc-res");
*length = 0; /* set length zero */
return NULL; /* return NULL indicating failure */
}
并且在为 res[t]
分配失败的情况下,您需要 free()
每个先前分配的结构 和 return 之前的指针避免造成内存泄漏,例如
if(sum = isSumSquare(i))
{ /* allocate for res[t] and validate, free all on failure */
if (!(res[t] = malloc (sizeof *res[t]))) {
perror ("malloc-res[t]");
while (t--) /* free previously allocated structs */
free (res[t]);
free (res); /* free pointers */
*length = 0; /* set length zero */
return NULL; /* return NULL indicating failure */
}
res[t].first = i;
res[t].snd = sum;
t++;
}
根据我对你需要做什么的最佳理解,你可以把它和类似的东西放在一起:
Pair **listSquared (long long m, long long n, int *length)
{
Pair **res = malloc ((n-m) * sizeof *res);
int t = 0;
long long sum = 0;
if (!res) { /* validate EVERY allocation */
perror ("malloc-res");
*length = 0; /* set length zero */
return NULL; /* return NULL indicating failure */
}
for(int i = m; i<=n; i++)
{
if(sum = isSumSquare(i))
{ /* allocate for res[t] and validate, free all on failure */
if (!(res[t] = malloc (sizeof *res[t]))) {
perror ("malloc-res[t]");
while (t--) /* free previously allocated structs */
free (res[t]);
free (res); /* free pointers */
*length = 0; /* set length zero */
return NULL; /* return NULL indicating failure */
}
res[t].first = i;
res[t].snd = sum;
t++;
}
}
*length = t;
return res;
}
在分配失败的情况下,您的函数 returns NULL
并释放了它在失败点之前分配的所有内存,消除了所有潜在的内存泄漏。
很高兴您能正常工作并提交了您的代码。如果您对上述推理有任何疑问,请发表评论,我很乐意进一步提供帮助。