|
|
发表于 2005-3-22 14:11:56
|
显示全部楼层
呵呵,又是指针和数组的区别。先看一段程序:
- int f(int *s[])
- {
- return *s[0];
- }
- int main(void)
- {
- int n1 = 7, n2 = 8;
- int a[][1] = { 7, 8, };
- int *b[] = { &n1, &n2, };
- f(a);
- f(b);
- return 0;
- }
复制代码
再看它的汇编代码(为了适合阅读已经排版):
- .file "x.c"
- .text
- .globl f
- .type f, @function
- f:
- pushl %ebp
- movl %esp, %ebp
- movl 8(%ebp), %eax
- movl (%eax), %eax
- movl (%eax), %eax
- popl %ebp
- ret
- .size f, .-f
- .globl main
- .type main, @function
- main:
- pushl %ebp
- movl %esp, %ebp
- subl $40, %esp
- andl $-16, %esp
- movl $0, %eax
- subl %eax, %esp
- ; n1 = 7
- movl $7, -4(%ebp)
- ; n2 = 8
- movl $8, -8(%ebp)
- ; a[][1] = { 7, 8, }
- movl $7, -16(%ebp)
- movl $8, -12(%ebp)
- ; b[] = { &n1, &n2, }
- leal -4(%ebp), %eax
- movl %eax, -24(%ebp)
- leal -8(%ebp), %eax
- movl %eax, -20(%ebp)
- ; f(a)
- leal -16(%ebp), %eax
- movl %eax, (%esp)
- call f
- ; f(b)
- leal -24(%ebp), %eax
- movl %eax, (%esp)
- call f
- movl $0, %eax
- leave
- ret
- .size main, .-main
- .section .note.GNU-stack,"",@progbits
- .ident "GCC: (GNU) 3.3.5 (Gentoo Linux 3.3.5-r1, ssp-3.3.2-3, pie-8.7.7.1)"
复制代码
可以看到,当用 a 做参数时,程序已经尝试访问(虚拟)地址为 7 的内存了。这当然会有段错误。
此外,全局的指针和数组不同,或者说,下面的声明和定义不是等价的:
- /* 第 1 个文件中 */
- int array[10];
- /* 另一个文件中 */
- extern int *array;
复制代码
原因也是类似的:请看一下编译器产生的汇编代码。 |
|