Objective-C中的可变大小数组?

4

好的,显然这个可以工作:

void foo(size_t s) {
    int myArray[s];
    // ... use myArray...
}

这真的合法吗?我的意思是,毕竟它可以编译通过(C编译器会将其拒绝为非常量)。我的第一个问题是:这是如何工作的?我认为它在堆栈上分配内存?这与使用alloca()有什么不同吗?

实际上,我找到了一些这样的代码:

void bar(size_t chunkSize) {
    CFReadStreamRef foo = NULL;
    // ...some stuff to init foo...

    while (stuffToDo) {
        UInt8 buffer[chunkSize];
        // ...read some data from stream into buffer
        //    using CFReadStreamRead()...
    }
}

这个可以运行。但是,当我将缓冲区分配从循环内部移动到函数的第一行(就在声明foo之前),该函数...停止工作。在调试器中,它到达了本地变量的第一个访问,然后就退出了。我没有看到任何异常被抛出,它不会崩溃,程序只是继续运行(实际上,函数返回一个字符串,该返回值为NULL,这是初始化返回变量的值)。我不确定发生了什么。基于第一部分,第二个问题是,到底发生了什么?
1个回答

3

在C99中,虽然很危险,但这是合法的,而且确实像alloca一样。

因为它像alloca一样,所以在堆栈上分配时要用合理大小的数组。如果长度为零,则我不确定是否定义了它,但如果数组“足够大”,则肯定会导致堆栈溢出。

至于发生了什么-如果大小合理,将其从循环中提取应该没有任何区别。我怀疑您看到未定义的行为,因为参数值过大(或者可能为0)-您应该验证chunkSize参数。汇编代码将告诉您为什么将其从循环中提取会产生差异(假设程序中的其他内容都是完整的)。


显然,我发现一些来源称其为危险的,而且显然确实如此。但我想了解它为何危险以及如何正确使用它。 - i_am_jorf
1
@jeffamaphone:因为char foo[some_large_value]有可能会导致堆栈溢出。实际上,这个特性没有什么好的理由存在。 - Ed S.
@EdS. 同意,我也避免使用这个功能。 - justin
是的... 这段代码存在各种问题,我正在修复它。除了其他不好的事情外,我们也不再这样做了。但我首先想了解它为什么/如何工作。 - i_am_jorf
@jeffamaphone 好的 - 我还添加了一些关于你帖子后半部分的内容。 - justin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接