我的座右铭是在系统中以最小的负载将一些虚拟数据写入文件。数据的大小未知并在运行时指定。
为此我可以想到2个解决方案。
1)使用动态内存分配
reserve_size_in_file (int reserve_size, FILE *fp)
{
char *p
p = malloc(reserve_size)
fwrite(p, sizeof(*p), 1, fp);
free(p);
}
2)使用数组
reserve_size_in_file (int reserve_size, FILE *fp)
{
char arr[reserve_size];
fwrite(arr, sizeof(arr), 1, fp);
}
我认为第二种方法不能用于声明一个长度可变的数组(ewww ...),我认为是不允许的。但它正在发挥作用。现在我的问题是,可以这样使用它吗?此外,如果有另一种更好的方法,请建议。
注意:我无法使用fallocate()
,因为我只需处理流IO。
修改:
我刚看到我可以使用fileno(fp)并使用fallocate()。但是我没有看到很多使用fallocate()的应用程序。使用fallocate()
是否有任何问题例如:fallocate(fileno(fp), 0, 0, 100000);
答案 0 :(得分:3)
Variable length arrays( VLA )是C99标准功能,只要您知道将使用支持C99的所有编译器,就可以使用它。 C11标准虽然可变长度数组可选。 gcc和clang都支持VGA甚至在C99模式之外作为扩展。另一方面,Visual Studio
直到最近才支持C99,我认为它们还不支持VLA。
如果您不知道提前的大小,可以选择通过malloc进行动态内存分配。
正如Jens所指出的,如果数组的大小很大,那么VLA会进入堆栈并且你有limited stack space这可能是一个问题,如果是这种情况,那么你将不得不使用动态内存。
答案 1 :(得分:2)
VLA有两个缺点
因此,除非您确定您的阵列永远不会超过一些数据,否则我不会为此选择它们。否则,如果分配失败,您将因堆栈溢出而出现虚假错误。
答案 2 :(得分:2)
我这样做:
reserve_size_in_file (int reserve_size, FILE *fp)
{
/* Usual HDDs have a block size of 512, but big
* block storage is becoming popular. */
char arr[4096];
/* initialize to 0xff, since runs of NUL bytes might
* be transparently replaced with sparse file holes. */
memset(arr, 0xff, sizeof(arr));
while(reserve_size > sizeof(arr)) {
fwrite(arr, sizeof(arr), 1, fp);
reserve_size -= sizeof(arr);
}
fwrite(arr, reserve_size, 1, fp);
}
这完全避免了动态内存分配,并且可以很好地处理块大小。