我们继续讨论关于指针传递内存的问题
《高质量C/C++程序设计指南》中这样用是正确
void GetMemory2(char **p, int num)
{
*p = (char*)malloc(sizeof(char)*num);
}
int main()
{
char *str =NULL;
GetMemory2(&str, 100);
strcpy(str, "hello");
printf("%s",str);
free(str);
getchar();
}
但其原因解释得也很含糊,我们同样可以一通过查看汇编代码的方式来窥探其中的奥秘
以下是GetMemory2函数
.file "zhengque.c"
.text
.align 2
.p2align 2,,3
.globl GetMemory2
.type GetMemory2,@function
GetMemory2:
pushl %ebp
movl %esp, %ebp
subl $20, %esp
pushl 12(%ebp) //100压入堆栈
call malloc //调用malloc函数
movl 8(%ebp), %edx //&str---->%edx
movl %eax, (%edx) //malloc申请了一块长度为100字节的内存空间
然后将指向这块空间的首地址作为返回值放入%eax,在把%eax的内容放入(%edx),而(%edx)正是str
malloc返回后的地址最终被放入了str中
这正是我们需要的
上面的4行实际上就相当于
*p = (char*)malloc(sizeof(char)*num);
p的内容实际上就是&str
*p自然就是str
以下是main函数:
leave
ret
.Lfe1:
.size GetMemory2,.Lfe1-GetMemory2
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "%s"
.text
.align 2
.p2align 2,,3
.globl main
.type main,@function
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
subl $8, %esp
leal -4(%ebp), %eax //将&str的值放入%eax
pushl $100 //100压入堆栈
pushl %eax //%eax内容也就是&str的值压入堆栈
movl $0, -4(%ebp)
call GetMemory2 //调用GetMemory2函数
movl -4(%ebp), %eax //str----->%eax
movl $1819043176, (%eax) //"hello"放入str指向的空间
movw $111, 4(%eax)
popl %ecx //恢复%ecx
popl %eax //恢复%eax
pushl -4(%ebp) //传递str作为参数,此时str指向了刚才开辟的空间,而空间里是"hello"
pushl $.LC0
call printf
popl %edx
pushl -4(%ebp)
call free
popl %eax
pushl stdin
call _IO_getc
addl $16, %esp
leave
ret
.Lfe2:
.size main,.Lfe2-main
.ident "GCC: (GNU) 3.2 20020903 (Red Hat Linux 8.0 3.2-7)"