关于c++中类的内存分配的有关问题

关于c++中类的内存分配的问题!大家好! 我想问个问题,是关于类的内存分配的,如下:class People{public:Peop

关于c++中类的内存分配的问题!
大家好! 我想问个问题,是关于类的内存分配的,如下:


class People
{
public:
People(void);
~People(void);
virtual void Test();
int i;
};



class Man :
public People
{
public:
Man(void);
~Man(void);
//void Test();
void A();
int al;
int j;
private:
void aa();
};



People *pp = new People(); //我现在在内存里实例化了一个父类。
pp->i = 7;
Man *ppp = (Man*)pp;       //现在把这个实例的指针给子类,我的疑问是,这个指针指的是父类
ppp->al = 7;              //应该没有子类中相应函数、变量的内存地址,那么这个子类是怎么
cout<<ppp->i<<ppp->al;    //调用自己的函数的呢?
ppp->A()

谢谢!
[解决办法]
有张表vtbl,派生类的数据是在派生后,在该表的尾部插入你的数据,在访问时,首先是取出vptr的值,这个值就是vtbl的地址,再根据这个值来到vtbl这里,由于调用的函数People的第一个虚函数,所以取出vtbl第一个slot里的值,这个值就是A()的地址了,最后调用这个函数。现在我们可以看出来了,只要vptr不同,指向的vtbl就不同,而不同的vtbl里装着对应类的虚函数地址,所以这样虚函数就可以完成它的任务。

[解决办法]
可能会出现内存错误的问题,调用子类函数时,相当于直接跳转至该函数的地址,然后将ppp指针指向的地址传入当做this,再往下如果不调用man类的成员,是不会出错,如果调用成员变量,则相当于在访问未分配的内存区域,就相当于C里面直接使用野指针了
[解决办法]
//应该没有子类中相应函数、变量的内存地址,那么这个子类是怎么调用自己的函数的呢?

非虚函数的话是静态绑定的, 在编译的时候就确定了调用的函数地址. 而不是运行的时候到对象上面去找的.
访问变量的时候直接就是越界访问. 就好比你 malloc 了 4 个字节的内存, 访问的时候按 8 个字节来访问, 后面的 4 个字节内容是未定义的. 而且进行写入的话很可能会覆盖堆的管理区, 导致随后的内存分配失败!
[解决办法]
引用:
Quote: 引用:

Quote: 引用:

谢谢您的回答,但是我这个能够访问,而且正常,没有出现越界的问题。怎么回事?
Quote: 引用:

//应该没有子类中相应函数、变量的内存地址,那么这个子类是怎么调用自己的函数的呢?

非虚函数的话是静态绑定的, 在编译的时候就确定了调用的函数地址. 而不是运行的时候到对象上面去找的.
访问变量的时候直接就是越界访问. 就好比你 malloc 了 4 个字节的内存, 访问的时候按 8 个字节来访问, 后面的 4 个字节内容是未定义的. 而且进行写入的话很可能会覆盖堆的管理区, 导致随后的内存分配失败!



越界访问出现了, 并不代表就会产生错误.
越界后的行为是未定义的, 正常运行也属于未定义的范畴.

你直接这样:

int main()
{
int* x = new int[1];
x[2] = 10;
printf("%d", x[2]);
}


程序都有可能是正常运行的, 难道因为没有报错, 你也说上面没有越界吗?


但是 现在的问题是,这个程序越界了,ppp->A() 这个A()是原来没有分配内存空间的,但是却完美执行了里面的内容,这个我比较奇怪,麻烦答疑~ 谢谢!

void Man::A()
{
cout<<"A"<<endl;
aa();  //这个函数也运行的很好。
}


函数是在代码段的, 又不需要占用对象的空间, 也不需要在对象上为它分配空间. 如果你的 aa 函数没有访问类的成员变量的话, 这样写都一样运行得很好:

   ((Man*)0)->A();


[解决办法]
People *pp = new People(); //我现在在内存里实例化了一个父类。
pp->i = 7;
Man *ppp = (Man*)pp;       //现在把这个实例的指针给子类,我的疑问是,这个指针指的是父类
ppp->al = 7;              //应该没有子类中相应函数、变量的内存地址,那么这个子类是怎么
cout<<ppp->i<<ppp->al;    //调用自己的函数的呢?
ppp->A()
调用没有一点问题,有问题的是调用会出错,
1)有虚函数的话,虚函数的地址不对。
2)这子类类指针,和野指针差不多,没有子类相应的数据,也没有子类的虚函数表指针,那个指针指向的是父类的虚函数表,和数据,不会处理子类的数据。
3)如果调用非虚函数,那个指针指向父类,没有子类的数据,处理子类数据(读,写)都是错误的,因为调用的是子类的非虚函数,这种函数,一般都会处理子类的数据的。

[解决办法]
你没出错只是你这个程序段很单一,如果是复杂的程序,很可能导致莫名其妙的错误。
特别是这行代码
ppp->al = 7; 
就好比数组越界,修改了本不该修改的地方的内存。