C99变长数组大小最大和sizeof功能 [英] C99 Variable Length Array Max sizes and sizeof Function

查看:519
本文介绍了C99变长数组大小最大和sizeof功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的C code采用可变长度阵列(沃拉斯)实验和尝试,以消除我的是什么,他们应该和不应该做的认识。

我有下面的代码片断从我的功能:

 无效get_pdw_frame_usb(pdws_t * pdw_frame,pdw_io_t * pdw_io)
{
...
unsigned char型BUF [pdw_io-> PACKET_SIZE]。
无符号字符* 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,<不完整的序列\\ 370 \\ 267 GT;

如果 pdw_io-> PACKET_SIZE 设置为12008(公平位大),然后我得到它看起来并不那么好以下内容:

 (GDB)p BUF
$ 29 = 0xbffe2d08

时的12008个字符太大了VLA?或者,也许这GDB的输出是不是担心,它只是看起来有点像它没有任何分配给我?

另外检查的大小时 BUF 我得到在这两种情况下以下内容:

 (GDB)芘的sizeof(BUF)
$ 30 = 0

我本来预计将在第一实​​例8和12008在2

我错了思维,应该可以使用的sizeof 函数以这种方式与VLA?

我的问题是,随后的USB批量传输失败,我想尝试排除它可能是与我的使用沃拉斯,这是一个有点新的领域,为我的事实..

更新

写了以下最低,完整,希望核查的程序,试图确认我的意见:

 的#include<&stdio.h中GT;无效test_vla(为size_t N)
{
    unsigned char型BUF [N];
    的printf(sizeof的BUF =%祖\\ n,sizeof的BUF);
}诠释的main()
{
    test_vla(12008);
    返回0;
}

现在,如果我打破使用gdb的的printf 语句,并运行点sizeof的BUF 我得到0,但的printf 输出12008.

GDB 的版本是:

 (GDB)显示版本
GNU GDB(Ubuntu的7.7.1-0ubuntu5〜14.04.2)7.7.1


解决方案

您正在运行到的问题是一个bug(或者更准确缺少的功能)的 GDB GDB 不正确处理的sizeof 操作者施加在VLA(可变长度数组)。

从gdb的邮件列表,此消息表明在沃拉斯的的支持的sizeof GDB 得到落实,但只是最近。显然,这是不是在你的版本,我使用的是(GDB 7.7.1)两种。如果没有该修补程序,它错误地打印VLA的大小为0。您的code本身应该表现正常;它只是 GDB 未被处理正确。

有什么特别不对您code,只要(一)它与支持沃拉斯,和(b)的数组的大小是积极的,不是太大的编译器编译。 (沃拉斯中不支持C90,也许除了作为扩展,引入了在C99的标准功能,并在C11作了可选)。

一个可能的解决方法是修改程序,以 sizeof的VLA 的值保存到变量,然后可以从 GDB

GDB 的另一个问题是打印VLA对象本身的行为比打印一个固定大小的数组对象不同。它显然把一个VLA为指针,以它的第一个元素,而不是作为一个数组对象。

下面是一个 GDB 成绩单,说明这个问题:

  GNU GDB(Ubuntu的7.7.1-0ubuntu5〜14.04.2)7.7.1
[SNIP]
(GDB)名单
1#包括LT&;&stdio.h中GT;
2#包括LT&;&string.h中GT;
3 INT主要(无效){
4 INT LEN = 6;
5 CHAR VLA [LEN]
6常量为size_t vla_size = sizeof的VLA;
7字符ARR [6];
8的strcpy(VLA,你好);
9的strcpy(ARR,世界);
10}
(GDB)破10
断点1日0x400600:文件C.C,10号线。
(GDB)运行
启动程序:/家庭/ KST / C断点1,主要的()在C.C:10
10}
(GDB)打印的sizeof VLA
$ 1 = 0
(GDB)打印vla_size
$ 2 = 6
(GDB)打印的sizeof ARR
$ 3 = 6
(GDB)打印VLA
$ 4 = 0x7fffffffdc10你好
(GDB)打印ARR
$ 5 =世界
(GDB)打印ARR + 0
$ 6 = 0x7fffffffdc40世界
(GDB)继续
继续。
[劣质1(28430工艺)正常退出]
(GDB)退出


  

时的VLA 12008字符是否过大?


大概不会。对于大多数实施方式中,VLA可以只是作为一个固定大小的数组一样大。有没有真正的区别(在内存中分配而言):

  {
    INT大小= 12008;
    CHAR BUF【规格】;
}

  {
    INT BUF [12008]
}

许多系统限制的内存可以在栈上分配的金额,但一个12008字节数组不太可能推动这些限制。

不过,如果你将要分配大型阵列,它可能会更好做这样通过的malloc()(这意味着你将需要显式调用免费()每个分配的对象)。

I am experimenting with the use of Variable Length Arrays (VLAs) in my C code and trying to iron out my understanding of what they should and shouldn't do.

I have the following snippet from my function:

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 is a data structure containing, amongst other things, packet_size, which is of type size_t

the char array buf is to be used to store the contents of a usb bulk transfer packet

I'm trying to instantiate it here as an automatic variable using the C99 VLA approach. I'm then trying to ensure its contents are all zeros.

I'm having a few issues.

Firstly, if pdw_io->packet_size is set to 8 (quite small), then buf is set to a reasonable looking value, i.e. debugging with gdb i can inspect it as follows:

(gdb) p buf
$27 = 0xbffe5be8 "\270", <incomplete sequence \370\267>

If pdw_io->packet_size is set to 12008 (fair bit larger), then I get the following which doesn't look so good:

(gdb) p buf
$29 = 0xbffe2d08 ""

Is 12008 chars too large for a VLA? Or perhaps that gdb output is not something to worry about, it just looks a bit like it hasn't allocated anything to me?

Also when inspecting the size of buf I get the following in both cases:

(gdb) p sizeof(buf)
$30 = 0

which I would have expected to be 8 in the 1st instance and 12008 in the 2nd

Am I wrong in thinking it should be possible to use the sizeof function in this way with a VLA?

My problem is that the subsequent usb bulk transfer is failing and I want to try and rule out the fact it may have something to do with my use of VLAs, which are a bit of a new area for me..

UPDATE

Wrote the following minimal, complete and hopefully verifiable program to try and confirm my observations:

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

now if I break on the printf statement with gdb and run p sizeof buf I get 0 but printf outputs 12008.

gdb version is:

(gdb) show version
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1

解决方案

The problem you're running into is a bug (or perhaps more accurately a missing feature) in gdb. gdb does not correctly handle the sizeof operator applied to a VLA (variable-length array).

This message from a gdb mailing list indicates that support for sizeof on VLAs has been implemented in gdb, but only relatively recently. Apparently it isn't in the version you and I are both using (gdb 7.7.1). Without that fix, it incorrectly prints the size of a VLA as 0. Your code itself should behave correctly; it's just gdb that isn't handling it properly.

There's nothing particularly wrong with your code, as long as (a) it's compiled with a compiler that supports VLAs, and (b) the size of the array is positive and not too large. (VLAs are not supported in C90, except perhaps as an extension, were introduced as a standard feature in C99, and were made optional in C11.)

A possible workaround is to modify your program to save the value of sizeof vla to a variable that you can then print from gdb.

Another problem with gdb is that printing the VLA object itself behaves differently than printing a fixed-size array object. It apparently treats a VLA as a pointer to its first element rather than as an array object.

Here's a gdb transcript that illustrates the problem:

GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
[SNIP]
(gdb) list
1       #include <stdio.h>
2       #include <string.h>
3       int main(void) {
4           int len = 6;
5           char vla[len];
6           const size_t vla_size = sizeof vla;
7           char arr[6];
8           strcpy(vla, "hello");
9           strcpy(arr, "world");
10      }
(gdb) break 10
Breakpoint 1 at 0x400600: file c.c, line 10.
(gdb) run
Starting program: /home/kst/c 

Breakpoint 1, main () at c.c:10
10      }
(gdb) print sizeof vla
$1 = 0
(gdb) print vla_size
$2 = 6
(gdb) print sizeof arr
$3 = 6
(gdb) print vla
$4 = 0x7fffffffdc10 "hello"
(gdb) print arr
$5 = "world"
(gdb) print arr+0
$6 = 0x7fffffffdc40 "world"
(gdb) continue
Continuing.
[Inferior 1 (process 28430) exited normally]
(gdb) quit

Is 12008 chars too large for a VLA?

Probably not. For most implementations, a VLA can be just as large as a fixed-size array. There's no real difference (in terms of memory allocation) between:

{
    int size = 12008;
    char buf[size];
}

and

{
    int buf[12008];
}

Many systems limit the amount of memory you can allocate on the stack, but a 12008-byte array isn't likely to push those limits.

Still, if you're going to be allocating large arrays, it's probably better to do so via malloc() (which means you'll need to explicitly call free() for each allocated object).

这篇关于C99变长数组大小最大和sizeof功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆