为什么解除引用主函数不显示内存内容?

时间:2014-05-21 14:14:00

标签: c pointers function-pointers dereference

我试图获取函数名[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));
    }

5 个答案:

答案 0 :(得分:3)

您无法取消引用函数本身,因为在解除引用它的上下文中它将成为函数指针。并且,当你取消引用它时,你会得到同样的旧功能......

您可以尝试:

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

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

答案 1 :(得分:2)

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

  • abc给出了一个指向函数的指针。
  • &abc也给出了一个指向函数的指针。
  • *abc给出了一个函数指示符。

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

所以abc&abc*abc都会给你相同的地址。

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

答案 2 :(得分:1)

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

#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] );
   }    
}

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

答案 3 :(得分:1)

在C中,函数指针的行为与常规指针不同 - 无论是使用取消引用还是使用address-of运算符,它仍然是对函数的引用。为了实现您的目标,您需要将其转换为不同的指针类型;例如:

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

答案 4 :(得分:0)

指向函数的指针不会被视为指向对象的指针,并且您不能将函数指针视为任意字节数组,就像使用对象指针一样。

如果您愿意违反一些规则,可以尝试为对象指针指定一个函数指针,如

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

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

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