c99变长数组,C99变长数组大小最大和sizeof功能

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",

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

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

2 #include

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).

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值