C 动态分配文件指针数组

C 动态分配文件指针数组,c,arrays,pointers,dynamic-allocation,file-pointer,C,Arrays,Pointers,Dynamic Allocation,File Pointer,是否可以在C中“动态”分配文件指针? 我的意思是: FILE **fptr; fptr = (FILE **)calloc(n, sizeof(FILE*)); 其中n是整数值。 我需要一个指针值数组,但在获得用户输入之前,我不知道有多少个指针值,所以我无法硬编码。 任何帮助都太好了 无论如何,它只是指针,所以您可以为它们分配内存 但是不要忘记fclose()每个文件指针,然后free()内存您试图实现一个有时被称为灵活数组(或灵活数组)的东西,也就是在程序生命周期内动态改变大小的数组。)这样

是否可以在C中“动态”分配文件指针? 我的意思是:

FILE **fptr;
fptr = (FILE **)calloc(n, sizeof(FILE*));
其中n是整数值。 我需要一个指针值数组,但在获得用户输入之前,我不知道有多少个指针值,所以我无法硬编码。
任何帮助都太好了

无论如何,它只是指针,所以您可以为它们分配内存
但是不要忘记
fclose()
每个文件指针,然后
free()
内存

您试图实现一个有时被称为灵活数组(或灵活数组)的东西,也就是在程序生命周期内动态改变大小的数组。)这样的实体在C的原生类型系统中不存在,所以你必须自己去实现它。在下面,我将假定
T
是数组中的元素类型,因为这个想法与任何特定类型的内容都没有任何关系。(在您的例子中,
T
FILE*

或多或少,您需要一个如下所示的结构:

struct flexarray {
    T *array;
    int size;
}
和一系列函数来初始化和操作这个结构。首先,让我们看一下基本访问器:

T  fa_get(struct flexarray *fa, int i) { return fa->array[i]; }
void fa_set(struct flexarray *fa, int i, T p) { fa->array[i] = p; }
int fa_size(struct flexarray *fa) { return fa->size; }
请注意,为了简洁起见,这些函数不进行任何错误检查。在现实生活中,您应该在
fau-get
fau-set
中添加边界检查。这些函数假定
flexarray
已经初始化,但没有说明如何进行初始化:

void fa_init(struct flexarray *fa) {
    fa->array = NULL;
    fa->size = 0;
}
请注意,这会将flexarray启动为空。让这样一个初始值设定项创建一个固定最小大小的数组是很常见的,但从零开始可以确保您执行数组增长代码(如下所示),并且在大多数实际情况下几乎不需要任何成本

最后,如何使flexarray更大?其实很简单:

void fa_grow(struct flexarray *fa) {
    int newsize = (fa->size + 1) * 2;
    T *newarray = malloc(newsize * sizeof(T));
    if (!newarray) {
        // handle error
        return;
    }
    memcpy(newaray, fa->array, fa->size * sizeof(T));
    free(fa->array);
    fa->array = newarray;
    fa->size = newsize;
}
请注意,flexarray中的新元素是未初始化的,因此在从中提取之前,您应该安排将某些内容存储到每个新索引i中

通常来说,每次通过一些常量乘数来增长FlexArray是一个好主意。相反,如果您以恒定增量增加它的大小,则需要花费二次时间来复制数组中的元素


我没有展示缩小数组的代码,但它与增长代码非常相似,

这样的数组的原因是什么?如果你想要一个文件数组*你上面的代码可以工作。每个文件*都可以用
fptr[n]
索引。完成后一定要把所有的东西都关上,然后把积木放出来。我不会问你为什么要这么做。这就是你的问题=)@rkosegi-我想同时打开几个文件。这些文件是按顺序编号的,所以我想我可以通过循环来同时打开它们。是的,你可以。这只是一个指针数组。没有理由这么做。@Joseph:是的,当然……我的意思是,实际上这很酷。。。但我的代码似乎适用于我的案例。这仅仅是实现同样事情的另一种方式吗?使用
callloc()
,而不是
realloc()
,使用无意义的清除(并且没有有效增长块的机会),而不是
realloc()
,这将包括下一步要完成的复制。@unwind:对于是否应该使用
realloc
,人们的意见各不相同。它是通用的allocate/grow/shrink/free函数,对于单个入口点来说可能有点太多了。也就是说,我不会在这样的代码中使用
calloc
,我会使用
malloc
(或者,也许,
realloc
)。多亏@JimBalter提供了一些修复。@Kitchi:至少在你的帖子中,我只看到了
fptr
的一个作业。您如何选择提供给
calloc
n
?如果您最终需要的
FILE*
值比原来分配的空间多,会发生什么情况?在这种情况下,您需要以某种方式增加数组,这将类似于我在这里展示的代码。