还是不太明白这两个函数的区别, 一个是调用者清空堆栈, 可变参数, 一个是被调用者清空堆栈,不可变参数不知道函数怎么运行的, 所以堆栈怎么产生也不太明白, 堆栈如何产生的
// ? 这个函数有什么堆栈
void func()
{
}// ? 这个函数堆栈又是什么样,在函数退出时,堆栈怎么办
void func()
{
   int a = 0 ; // 定义了一个变量, 这个变量保存在堆栈中吗
    printf("%d" , a );
}// ? 这个函数会不会有堆栈,怎么样
void func()
{
   char *p = (char * ) malloc( sizeof(char)) ;
   free(p);
}

解决方案 »

  1.   

    _stdcall与_cdecl的作用,只对函数带有参数起作用,与函数内部变量无关,虽然内部变量也在栈中,但释放的时候是由函数在返回之前进行的。
    http://blog.csdn.net/zhoujianhei/archive/2008/03/12/2172964.aspx
      

  2.   

    _stdcall与_cdecl的作用 关于堆栈两种函数的局部变量是一样的, 关键是参数使用栈不一样而已_stdcall  在函数内部释放栈
      如汇编代码:   __asm   ret  4;_cdecl    需要调用函数的对象释放栈
      如汇编代码:   __asm   add  esp, 4
      

  3.   

    http://blog.csdn.net/na_he/archive/2008/05/07/2408655.aspx
    __stdcall调用约定相当于16位动态库中经常使用的PASCAL调用约定。在32位的VC++5.0中PASCAL调用约定不再被支持(实际上它已被定义为__stdcall。除了__pascal外,__fortran和__syscall也不被支持),取而代之的是__stdcall调用约定。两者实质上是一致的,即函数的参数自右向左通过栈传递,被调用的函数在返回前清理传送参数的内存栈,但不同的是函数名的修饰部分(关于函数名的修饰部分在后面将详细说明)。
    _stdcall是Pascal程序的缺省调用方式,通常用于Win32 Api中,函数采用从右到左的压栈方式,自己在退出时清空堆栈。VC将函数编译后会在函数名前面加上下划线前缀,在函数名后加上"@"和参数的字节数。
    2、C调用约定(即用__cdecl关键字说明)按从右至左的顺序压参数入栈,由调用者把参数弹出栈。对于传送参数的内存栈是由调用者来维护的(正因为如此,实现可变参数的函数只能使用该调用约定)。另外,在函数名修饰约定方面也有所不同。
    _cdecl是C和C++程序的缺省调用方式。每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大。函数采用从右到左的压栈方式。VC将函数编译后会在函数名前面加上下划线前缀。是MFC缺省调用约定。
      

  4.   

    只有清栈的时候有区别
    因此,stdcall不支持可变参数
      

  5.   

    _stdcall与_cdecl只是对于不同的编译器而言的, 如果都是用VC写的,就不需要关心, 如果用VC调用DELPHI写的DLL, 就需要关心,因为编译器不同这个我明白,我想知道,堆栈是如何产生的
      

  6.   

    stdcall与cdecl都是通过栈来传递参数,在调用函数时,从最右边的参数开始,依次向左逐个push到栈中,最后call函数地址,函数中根据刚刚进入函数时esp的值来访问这些参数,stdcall方式是在函数返回时利用ret指令清除栈中的参数,cdecl方式是函数返回后,由调用函数者修改esp的值来清除栈中的参数。
      

  7.   

    // ? 这个函数有什么堆栈
    ->栈中有函数的返回地址和EBP
    void func()
    {
    }// ? 这个函数堆栈又是什么样,在函数退出时,堆栈怎么办
    ->栈中有函数的返回地址、EBP和局部变量a,函数退出根据调用的方式,决定有哪个清理栈。
    void func()
    {
      int a = 0 ; // 定义了一个变量, 这个变量保存在堆栈中吗
        printf("%d" , a );
    }// ? 这个函数会不会有堆栈,怎么样
    -> 当然有栈里的内容是:函数的返回地址,EBP和指针p本身的地址。
    void func()
    {
      char *p = (char * ) malloc( sizeof(char)) ;
      free(p);
    }
      

  8.   

    _cdecl为了支持可变参数而使用.被调用者不知道有多少个参数近来了,没法add esp,参数个数 *4
    只好让调用者负责,这导致生成的EXE的文件稍大