问大家一道题:关于成员函数占多少内存

airwolf1216 2012-04-11 08:40:10
类的对象的内存布局,里面会有数据成员,但是没有函数成员(充其量里面可能有个vptr),难道类的成员函数本身不占内存?

这是第一个疑问,请教高手:成员函数不占内存吗?推而广之,一般的全局函数不占内存吗?如果占,那么函数该占多少内存,与什么有关(参数?还是函数体里的局部变量?)


第二个问题:
如果外层用一个int** 指针,去访问类的虚函数,我可以做到,但是无法访问类的normal函数,请问高人,能否做到:

#include <stdio.h>
typedef void (*PTRFUN)(void);//声明一个函数指针

class A
{
public:
int ia;
int ib;
void virtual fun1();//虚函数
void virtual fun2();
void virtual fun3();
void virtual fun4();
void fun5();//实函数,normal
A();
};
A::A()
{
ib=20;
ia=10;
}
void A::fun1()
{
printf("A::fun1()\n");
}
void A::fun2()
{
printf("A::fun2()\n");
}
void A::fun3()
{
printf("A::fun3()\n");
}
void A::fun4()
{
printf("A::fun4()\n");
}
void A::fun5()
{
printf("A::fun5()\n");
}


void main()
{

A b;
int **ptr=NULL;
ptr=(int **)&b;

PTRFUN ptrfun;

printf("ptr[0][0]=%d\n",(int)(ptr[0]));//这是强行解释vptr,没什么意义
printf("ptr[0][2]=%d\n",(int)(ptr[1]));//访问ia
printf("ptr[0][3]=%d\n",(int)(ptr[2]));//访问ib

//这是强行解释之后的编码,我是边调试边写的,顺便就能得出b的内存布局来
//这样能访问虚函数们
ptrfun=(PTRFUN)(ptr[0][0]);
ptrfun();//访问fun1
ptrfun=(PTRFUN)(ptr[0][1]);
ptrfun();//访问fun2
ptrfun=(PTRFUN)(ptr[0][2]);
ptrfun();//访问fun3
ptrfun=(PTRFUN)(ptr[0][3]);
ptrfun();//访问fun4
//我该如何访问fun5?
}

上面这个,如何通过ptr来访问fun5?是不是因为fun5不在对象内存中,因此无法访问得到?
请真正的高手进来解答我的疑问


(注:上面的代码,我采用了一种“投机取巧”的方式,那就是int和int*占的内存大小一样大。。。。要不然,收不到效果的)
我用的VC6.0+XP32位系统
...全文
651 38 打赏 收藏 转发到动态 举报
写回复
用AI写文章
38 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2012-04-15
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 的回复:]
引用 24 楼 的回复:

仅供参考
C/C++ code
//仅对VC6
#include <stdio.h>
void fun1() {
int f1=1;
printf("fun1\n");
printf("fun1\n");
}
void fun2() {
int f2=2;
printf("fun2\n");
}
void fun3() {
}
void……
[/Quote]
VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!
指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。”

提醒:
“学习用汇编语言写程序”

“VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习C和汇编的对应关系。”
不是一回事!

不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!
碎炎 2012-04-13
  • 打赏
  • 举报
回复
函数的二进制码在代码段的吧 运行的时候已经分配好了 所有的成员函数的调用都是用地址来调用其中的二进制码 函数名字仅仅只是一个符号而已 编译后就替换掉了 所以无论是成员函数还是静态函数 在编译后仅仅是个普通函数而已 调用的规则是在c++语法层面上的

占内存的是对象的成员,假设在栈上分配 ,则堆栈段会分配相应大小的内存 堆上分配的话 栈上分配一个指针大小的内存用于记录堆上的地址 对象的成员函数是不占数据区的内存的
bainaohdu 2012-04-13
  • 打赏
  • 举报
回复
所有的函数所占的内存都在代码区,不会占用对象的内存的
max_min_ 2012-04-13
  • 打赏
  • 举报
回复
每个程序都会有4G的虚拟内存,当程序运行时,系统会分配物理空间 形成映射,与虚拟内存对应起来

程序都有5个数据段
全局区:初始化的全局变量,静态的变量
代码区:主要是存放函数,还有一些 char* 的常量(可读不可改的)
BBS段: 未初始化的全局变量,运行时,都会清零
堆区:自己分配出来的内存 ,new /malloc/sbrk/等(必须自己释放,要不就内存泄露)
栈区:函数内部定义的局部变量,
失落的凡凡 2012-04-13
  • 打赏
  • 举报
回复
我觉得,看《深入理解计算机系统》比看《深度探索c++对象模型》更能消除你的困惑。
赵大牛的代码,是不会给你带来任何知识的。
一根烂笔头 2012-04-13
  • 打赏
  • 举报
回复
应用型c++程序员确实很少关心这个层次的东西。
自信男孩 2012-04-13
  • 打赏
  • 举报
回复
函数本身可以理解为地址,那么指针占用的内存数应该就是函数占用的内存吧
王二.麻子 2012-04-13
  • 打赏
  • 举报
回复
自己写个类(成员,函数,函数里面最好有些超级简单明白的代码,自己一眼就能看出来的那种),然后实例(要是麻烦,就给各个成员赋值成规则的数字,便于自己发现),

编译运行,输出实例的地址,然后记着地址,然后去调试器看内存结构...

实例:数据1,数据2数据3,...函数1地址,函数2地址,函数3地址,
...
函数1:{各种代码...}
函数2:{各种代码...}
...

实例可以在堆栈,堆...函数1,函数2都在程序代码段.
airwolf1216 2012-04-12
  • 打赏
  • 举报
回复
哦~看看明天结贴吧
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 的回复:]
你推荐几本好书吧 关于这一类问题的 <深入探索c++对象模型>就不必推荐了
[/Quote]
貌似就这一本书 说到这个问题了。

函数占多少内存,可以编译时输出map文件得到具体数值。
LLionTree 2012-04-12
  • 打赏
  • 举报
回复
typedef void (A::*Myfun)(void) ;
airwolf1216 2012-04-12
  • 打赏
  • 举报
回复
还有人回答吗
evencoming 2012-04-11
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 的回复:]
还有别的书介绍内存的吗
[/Quote]

学程序设计入门书:深入理解计算机系统
airwolf1216 2012-04-11
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 的回复:]
引用 10 楼 的回复:

引用 7 楼 的回复:
所有的函数所占的内存都在代码区。

那对象存在哪?

c++中对象是指一段储存空间,函数不是对象,无论它是否占储存空间.
可以看下<深度探索C++对象模型>,但是这本书是基于某个编译器的,不是基于C++的.
在C++中,理解到这里就行了.

如果你学汇编,就知道代码和数据的区别.
[/Quote]

还有别的书介绍内存的吗
iamnobody 2012-04-11
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

引用 7 楼 的回复:
所有的函数所占的内存都在代码区。

那对象存在哪?
[/Quote]
c++中对象是指一段储存空间,函数不是对象,无论它是否占储存空间.
可以看下<深度探索C++对象模型>,但是这本书是基于某个编译器的,不是基于C++的.
在C++中,理解到这里就行了.

如果你学汇编,就知道代码和数据的区别.

Coder_Y_Jao 2012-04-11
  • 打赏
  • 举报
回复
非虚成员函数不会被添加到对象内存中,因为它不需要在运行时确定函数调用,直接编译期就可以搞定
虚成员函数也不会添加到对象内存中,但会被编译器添加一个虚函数表指针,在运行时进行函数的查找调用。

函数本身的内存存放没有什么区别
jiaoyang12345 2012-04-11
  • 打赏
  • 举报
回复
A b;

为b分配存储空间时,只包括b的非静态数据成员,而b的成员函数却存储在代码段。
jiaoyang12345 2012-04-11
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]
引用 6 楼 的回复:
成员函数跟全局函数没什么区别,它当然占内存,但是不会在对象里面。因为他们在内存里只有一份。

那它们存在哪?
[/Quote]存在代码段。。。。。
airwolf1216 2012-04-11
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]
所有的函数所占的内存都在代码区。
[/Quote]
那对象存在哪?
airwolf1216 2012-04-11
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]
成员函数跟全局函数没什么区别,它当然占内存,但是不会在对象里面。因为他们在内存里只有一份。
[/Quote]
那它们存在哪?
加载更多回复(18)

64,632

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧