简体   繁体   English

C中可变大小的数组。可以吗?

[英]array of variable size in C. Is it ok?

My motto is to write some dummy data into the file with minimal load on the system. 我的座右铭是以最小的系统负载将一些虚拟数据写入文件。 The size of the data is not known and specified at run time. 数据大小未知,并且在运行时指定。

For this I can think of 2 solutions. 为此,我可以想到2个解决方案。

1) Using Dynamic memory allocation 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) Using arrays 2)使用数组

reserve_size_in_file (int reserve_size, FILE *fp) 
{
    char arr[reserve_size];
    fwrite(arr, sizeof(arr), 1, fp);
}

I thought the second method will not work as declaring an array with variable length(ewww...), i thought is not allowed. 我以为第二种方法不能像声明具有可变长度的数组那样工作(ewww ...),我认为这是不允许的。 But it is working. 但它正在工作。 Now my question is, is it ok to use it like this? 现在我的问题是,可以像这样使用它吗? Also, if there is another better way to do this pls suggest. 另外,如果还有其他更好的方法可以做到这一点,请提出建议。

Note: I cannot use fallocate() because I have to deal only with stream IO. 注意:我不能使用fallocate()因为我只需要处理流IO。

Edit: 编辑:

I just saw that i can use fileno(fp) and use fallocate(). 我只是看到我可以使用fileno(fp)和使用fallocate()。 But i donot see many applications using fallocate(). 但是我看不到许多使用fallocate()的应用程序。 Are there any concerns in using fallocate() 使用fallocate()是否有任何问题

Ex: fallocate(fileno(fp), 0, 0, 100000); 例如: fallocate(fileno(fp), 0, 0, 100000);

Variable length arrays ( VLA ) are a C99 standard feature and are ok to use as long as you know all the compilers you will use support C99. 可变长度数组VLA )是C99的标准功能,只要您知道将使用的所有编译器都支持C99,就可以使用。 the C11 standard though made variable length arrays optional. 尽管C11标准使可变长度数组成为可选。 Both gcc and clang support VLAs even outside of C99 mode as an extension. gccclang甚至在C99模式之外都支持VLA作为扩展。 Visual Studio on the other hand did not support C99 until recently and I don't think they support VLA yet. 另一方面, Visual Studio直到最近才支持C99,我认为它们还不支持VLA。

The alternative if you don't know the size ahead of time is dynamic memory allocation via malloc. 如果您不提前知道大小,可以选择通过malloc动态分配内存。

As Jens points out, VLAs do go on the stack and you have limited stack space which can be a problem if the size of your arrays is large, if that is the case then you will have to use dynamic memory. 正如Jens指出的那样,VLA确实会进入堆栈,并且堆栈空间有限 ,如果阵列的大小很大,这可能是个问题,如果是这种情况,则必须使用动态内存。

VLA have two disadvantages VLA有两个缺点

  • you don't know how much data you can reserve "on the stack" for them 您不知道可以为他们“堆栈上”保留多少数据
  • there is no error return if the allocation doesn't succeed. 如果分配不成功,则不会返回错误。

So unless you know for sure that your array will never go beyond some kilo of data, I'd not chose them for this purpose. 因此,除非您确定您的阵列永远不会超出数以千计的数据,否则我不会为此选择它们。 Otherwise if the allocation fails you'd have spurious errors due to stackoverflow. 否则,如果分配失败,则由于stackoverflow而导致虚假错误。

I'd do it like this: 我会这样:

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);
}

This completely avoids the dynamic memory allocation and operates in nice to work with block sizes. 这完全避免了动态内存分配,并且可以很好地与块大小一起使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM