您的位置:首页 > 其它

C99中变长数组的内存分配策略

2013-10-17 11:50 127 查看
在C99中新加入了对变长数组的支持,也就是说数组的长度可以由变量来定义。

对于下面的代码:

int main()

{

int n;

scanf("%d", &n);

int ar
;

printf("%d\n", sizeof(ar));

return 0;

}

是可以成立的。

这与之前的C标准有很大不同,以前的数组大小只能由常量来指定,也就是编译器在编译时就可以确定为数组分配多少存储空间,一般来说,一个活动记录的大小在进入一个函数的时候就可以确定下来。这个变长数组的特性必定把数组的分配引入了运行时期,附带的,sizeof这个原来的编译期操作也不得不被带入到运行时期。那么,对于动态数组的实现,编译器必定要生成一些代码来对其进行runtime的支持,这必定有损效率。

GCC编译得到代码

.file "d.c"

.section .rodata.str1.1,"aMS",@progbits,1

.LC0:

.string "%d"

.LC1:

.string "%d\n"

.text

.globl main

.type main, @function

main:

pushl %ebp

movl %esp, %ebp

pushl %ebx

subl $36, %esp

andl $-16, %esp

subl $16, %esp

movl %esp, %ebx

leal -8(%ebp), %eax

movl %eax, 4(%esp)

movl $.LC0, (%esp)

call scanf

movl -8(%ebp), %edx

addl %edx, %edx

addl %edx, %edx

leal 30(%edx), %eax

andl $-16, %eax

subl %eax, %esp

movl %edx, 4(%esp)

movl $.LC1, (%esp)

call printf

movl %ebx, %esp

xorl %eax, %eax

movl -4(%ebp), %ebx

leave

ret

.size main, .-main

.ident "GCC: (GNU) 4.0.3 (Ubuntu 4.0.3-1ubuntu5)"

.section .note.GNU-stack,"",@progbits

省略无关代码

movl -8(%ebp), %edx //n的值

addl %edx, %edx

addl %edx, %edx //edx = edx*4 ,int是4字节的,所以数组占用的空间是4*n

leal 30(%edx), %eax

andl $-16, %eax //字节对齐

subl %eax, %esp //分配存储空间,仍然是在栈里面

这里的空间分配是在栈里完成的

而且没有进行系统调用

所以根本没有额外的碎片所需要的费用

多分配空间是为了进行字节对其
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: