指针传递内存深入探讨(二)

 我们继续讨论关于指针传递内存的问题

《高质量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)"


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值