假设我想写(在C99中)以下函数:
NAME: primes
INPUT: an integer n > 0
OUTPUT: int array filled with the prime numbers in range [2, n]
如何从我的函数中返回这样的数组?那可能吗?
请注意,我不希望调用者分配一个我将用0(复合)和1(素数)填充的n * sizeof(int)
数组。
我不能只返回指向数组的指针,因为调用者无法知道数组有多长:
int * primes(int n)
{
int * arr = malloc(n * sizeof(int));
// do stuff
return arr;
}
int main(void)
{
int * arr = primes(100);
printf("%lu \n", sizeof arr); // prints 8
}
我无法像这样更改签名:
int (*primes(int n))[LENGTH]
因为LENGTH在编译时是未知的。
我在某处读到类似“返回带有数组的结构是一个可怕的想法”,而且......好吧......这是我的最后一个想法。
在这种情况下,最佳做法是什么?
答案 0 :(得分:7)
如果您调用的函数必须确定需要分配的实际元素数,则应该将指针传递给分配的长度以及其余参数,如下所示:
size_t actual_length;
int *arr = primes(100, &actual_length);
if (arr == NULL) {
... // Report an error
}
for (size_t i = 0 ; i != actual_length ; i++) {
printf("%d\n", array[i]);
}
primes
将如下所示:
int *primes(int count, size_t *actual_length) {
size_t primes_needed = ...
int *res = malloc(sizeof(*res)*primes_needed);
*actual_length = primes_needed;
// Do calculations, perhaps some reallocs
// Don't forget to reassign *actual_length = ... on realloc
...
return res;
}
答案 1 :(得分:3)
使用malloc
分配数组时,您无法使用sizeof
请求其大小。在这些情况下的常见做法是返回数组的大小并将其分配给作为参数给出的指针指针。像这样:
int primes(int n, int ** arr){
int length = n;
*arr = malloc(length * sizeof(int));
// do stuff...
// if *arr is realloc()ed update length
return length;
}
然后像这样调用它:
int * arr;
length = primes(100, &arr);
执行此操作的标准函数的示例是fread
。它将一个数组和元素的数量(以及元素的大小)作为参数。然后它返回它实际读取的元素数量,如果例如达到文件末尾,则可能更少。