Tag: 可变长度数组

VLA的记忆在gcc下可用

当malloc返回NULL时,有没有办法检测到使用VLA的堆栈上没有足够的内存?

长度为0的可变长度数组?

在C中,通常不允许数组的大小为0(除非我使用一个或其他编译器端扩展)。 OTOH,有长度可能为0的VLA。 他们被允许吗? 我在谈论以下代码: void send_stuff() { char data[4 * !!flag1 + 2 * !!flag2]; uint8_t cursor = 0; if (flag1) { // fill 4 bytes of data into &data[cursor] cursor += 4; } if (flag2) { // fill 2 bytes of data into &data[cursor] cursor += 2; } } 结果是一个长度为0,2,4或6的data数组,具体取决于标志的组合。 现在的问题是:对于数组结果长度为0的情况,这个有效代码是什么?

为什么零长度VLA UB?

2011年标准明确规定…… 6.7.6.2数组声明符 如果size是一个不是整数常量表达式的表达式:如果它出现在函数原型范围的声明中,则将其视为*被替换为* ; 否则,每次评估它时,其值应大于零。 变长数组类型的每个实例的大小在其生命周期内不会改变。 如果size表达式是sizeof运算符的操作数的一部分,并且更改size表达式的值不会影响运算符的结果,则无法指定是否计算size表达式。 这是设计的,但以下代码似乎是合理的。 size_t vla(const size_t x) { size_t a[x]; size_t y = 0; for (size_t i = 0; i < x; i++) a[x] = i; for (size_t i = 0; i < x; i++) y += a[i % 2]; return y; } Clang似乎为它生成合理的x64程序集(没有优化)。 显然索引零长度VLA没有意义,但访问超出边界会调用未定义的行为。 为什么零长度数组未定义?

C99可变长度arrays最大尺寸和尺寸function

我正在尝试在我的C代码中使用可变长度数组(VLA),并试图理解我们应该和不应该做什么。 我的函数有以下代码片段: void get_pdw_frame_usb(pdws_t *pdw_frame, pdw_io_t *pdw_io) { … unsigned char buf[pdw_io->packet_size]; unsigned char *pdw_buf; memset(buf, ‘\0’, sizeof(buf)); pdw_io是一个数据结构,其中包含packet_size ,其类型为size_t char数组buf用于存储usb批量传输数据包的内容 我试图在这里使用C99 VLA方法将其实例化为自动变量。 我正在努力确保其内容全部为零。 我有一些问题。 首先,如果pdw_io->packet_size设置为8(非常小),则将buf设置为合理的值,即使用gdb进行调试,我可以按如下方式检查: (gdb) p buf $27 = 0xbffe5be8 “\270”, 如果pdw_io->packet_size设置为12008(相当大),那么我得到以下看起来不太好的: (gdb) p buf $29 = 0xbffe2d08 “” 对于VLA,12008个字符是否太大? 或者也许gdb输出不值得担心,它看起来有点像它没有分配任何东西给我? 另外,在检查buf的大小时,我在以下两种情况下都会得到以下结果: (gdb) p sizeof(buf) $30 = 0 我原本预计在第一个实例中是8个,在第二个实例中是12008个 我认为应该可以通过VLA以这种方式使用sizeof函数,这是错误的吗? 我的问题是随后的usb批量传输失败了,我想尝试排除它可能与我使用VLA有关的事实,这对我来说是一个新的领域。 UPDATE 写下以下最小,完整且有希望validation的程序,以尝试确认我的观察结果: […]

C和C ++中的可变长度数组(VLA)

可能重复: 在文件范围内可变修改的数组 我有一些关于VLA及其行为的概念,我需要澄清一下。 自C99起AFIK可以将VLA声明为本地范围: int main(int argc, char **argv) { // function ‘main’ scope int size = 100; int array[size]; return 0; } 但它在全球范围内被禁止: const int global_size = 100; int global_array[global_size]; // forbidden in C99, allowed in C++ int main(int argc, char **argv) { int local_size = 100; int local_array[local_size]; return 0; } 上面的代码在C99中声明了一个VLA,因为const修饰符不会创建编译时值。 在C […]

桌面操作系统上的C编译器使用多少个内存页来检测堆栈溢出?

这个问题与C99中的可变长度数组有关但不同。 答案指出,在堆栈中分配可变长度数组(或者只是固定大小的大数组)的一个危险是分配可能会无声地失败,而不是调用malloc ,后者明确告诉调用者分配是否成功。 现代非嵌入式编译平台使用无效的内存区域来检测一些堆栈溢出,而无需额外成本(检查只是MMU已经免费进行的检查)。 这不能保证100%免受上述问题的影响,因为非常大的本地数组可能导致堆栈指针跳过无效区域。 是否有人知道通常为此检测分配了多少页? 我想这至少是4KiB,但它可能会更多。 这是由编译器或操作系统做出的选择,在任何一种情况下,有没有办法改变它?

如何在C99运行时计算可变长度数组的大小?

在C89中,数组的长度在编译时是已知的。 但在C99中,对于可变长度数组,数组的长度在运行时可能是未知的。 那怎么计算呢? 为什么不能以相同的方式计算动态分配的数组的长度?

没有malloc的C中的动态数组?

我一直想知道如何逃脱这个: int main(int argc, char **argv) { printf(“%p %s %d\n”, &argv[1], argv[1], strlen(argv[1])); char copy[strlen(argv[1]) + 1]; strcpy(copy, argv[1]); printf(“%p %s %d\n”, &copy, copy, strlen(copy)); return 0; } 无论如何,char数组copy都被分配,程序运行正常,打印出原始副本和副本。 而Valgrind并没有抱怨什么。 我认为没有malloc的C中不可能使用动态数组。 我错了吗?

可变长度数组的原型

我正在尝试编写一个在c中采用可变大小数组的函数。 void sort(int s, int e, int arr[*]){ … } 它表示对于可变长度数组,它需要在函数声明中有界。 那是什么意思? 我正在使用xcode 4.0,使用LLVM编译器2.0。 谢谢您的帮助。

struct中间的可变长度数组 – 为什么这个C代码对gcc有效

使用VLA(可变长度数组)有一些奇怪的代码,它被gcc 4.6视为有效C(C99,C11): $ cat ac int main(int argc,char**argv) { struct args_t{ int a; int params[argc]; // << Wat? // VLA in the middle of some struct, between other fields int b; } args; args.b=0; for(args.a=0;args.a<argc;args.a++) { args.params[args.a]=argv[0][0]; args.b++; } return args.b; } 编译时此代码没有警告: $ gcc-4.6 -Wall -std=c99 ac && echo $? 0 $ ./a.out ; […]