【问题标题】:Why dereferencing the main function does not show memory content?为什么取消引用 main 函数不显示内存内容?
【发布时间】:2014-07-10 06:01:04
【问题描述】:

我试图获取函数名 [abc() 和 main()] 指向的地址的内存内容,但函数内部的 printf() 都给出相同的输出,尽管我取消引用函数指向的地址每个函数内的第二个 printf() 中的名称。这是为什么?为什么 *(abc) 和 *(main) 打印内存地址而不是内容?

   #include<stdio.h>


    void abc(){

            printf("\n%p \n ", abc);
            printf("\n%#x\n ",*(abc));

    }


    void main(){

            abc();
            printf("\n%p \n ", main);
            printf("\n%#x\n ",*(main));
    }

【问题讨论】:

  • AFAIK,C 中没有像“函数体”这样的类型。如何实现printf 来实现这个目的?

标签: c pointers function-pointers dereference


【解决方案1】:

指向函数的指针与指向对象的指针不同,您不能像对待对象指针那样将函数指针视为任意字节数组。

如果您愿意打破一些规则,您可以尝试将函数指针分配给对象指针,如

unsigned char *data = (unsigned char *) abc;

然后检查data[i]的内容。

请注意,您的编译器应该抱怨这一点。根据平台的不同,这可能根本不起作用。 C 标准没有定义从函数指针类型到对象指针类型的转换,反之亦然。允许个人实施这样做,但这不是必需的。

【讨论】:

    【解决方案2】:

    在 C 中,函数指针的行为不像常规指针 - 无论您使用解引用还是地址操作符,它仍然是对函数的引用。为了实现您的目标,您需要将其转换为不同的指针类型;例如:

    void main()
    {
        printf("\n%p \n ", main);
        printf("\n%#x\n ", *((char*)main) );
    }
    

    【讨论】:

      【解决方案3】:

      您没有打印数据(实际上是代码),而是指向代码的指针的值。

      #include<stdio.h>
      
      void abc(){
      int i;
         printf("\n%p \n ", abc);
         printf("\n%#x\n ",*(abc));
         for( i = 0; i < 100; i++ ){
            printf( "%X ", ((unsigned char *)abc)[i] );
         }    
      }
      
      
      void main(){
      int i;
         printf("\n%p \n ", abc);
         abc();
         printf("\n%p \n ", main);
         printf("\n%#x\n ",*(main));
         for( i = 0; i < 100; i++ ){
            printf( "%X ", ((unsigned char *)main)[i] );
         }    
      }
      

      这表明代码在两个函数指针指向的地方是不同的。除非您在头脑中精通逆向汇编,否则这是相当无用的,但您应该能够验证它转储的代码是否与反汇编相应代码片段的调试器的输出一致。

      【讨论】:

        【解决方案4】:

        那是因为函数和函数指针的语法非常奇怪。

        • abc 给出一个函数指针。
        • &amp;abc 还提供了一个函数指针。
        • *abc 给出了一个函数指示符。

        函数指示符衰减为函数指针,因此当您在表达式中使用函数指示符时,您将获得函数的地址。

        所以abc、&amp;abc 和*abc 都会给你相同的地址。

        永远不要认为 C 是一种理性、理智、一致的语言!

        【讨论】:

        【解决方案5】:

        你不能取消引用一个函数本身,因为在取消引用它的上下文中它会变成一个函数指针。而且,当你取消引用它时,你会得到相同的旧函数......

        你可以试试:

        printf("one");
        (*printf)("two");
        (**printf)("three");
        

        要真正查看函数内容,您需要memcpy() 之类的内容。但是,这样做可能没有那么有用,因为没有办法获得函数的大小(至少通过任何标准方式)。如果您想查看函数的内容是什么样的,请将您的程序放在调试器中并反汇编该函数。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-10-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多