【发布时间】:2015-12-18 05:54:48
【问题描述】:
我正在尝试在我的 C 代码中使用可变长度数组 (VLA),并试图澄清我对它们应该做什么和不应该做什么的理解。
我的函数中有以下 sn-p:
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", <incomplete sequence \370\267>
如果 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 有关的事实,这对我来说是一个新领域..
更新
编写了以下最小、完整且希望可验证的程序来尝试确认我的观察结果:
#include <stdio.h>
void test_vla(size_t n)
{
unsigned char buf[n];
printf("sizeof buf = %zu\n", sizeof buf);
}
int main()
{
test_vla(12008);
return 0;
}
现在,如果我使用 gdb 中断 printf 语句并运行 p sizeof buf 我得到 0 但 printf 输出 12008。
gdb 版本是:
(gdb) show version
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
【问题讨论】:
-
@Olaf 什么都没有,计算错误。
-
请注意,编译器不需要支持 VLA:s 即可与 C11 兼容。这意味着出于可移植性的原因应该避免使用 VLA:s,并且它们可能会在未来的 C 标准中被删除。
-
@bph gdb 将 char 数组打印为以零结尾的字符串,因此输出告诉您的只是第一个字符为零。我认为您在这里没有实际问题。
-
您的更新没有使用 VLA,所以它当然不会触发问题。旧版本的 gdb 不支持 VLA 上的
sizeof;较新的版本可以。请参阅我的更新答案。
标签: c c99 variable-length-array