
求高手解答C++入门问题!!!
#include<iostream>usingnamespacestd;classAnimal{public:Animal():itsAge(1){}~Animal(){...
#include <iostream>
using namespace std ;
class Animal
{
public :
Animal ( ) : itsAge ( 1 ) { }
~Animal ( ) { }
virtual void Speak ( ) const { cout << " Animal speaking...\n " ; }
protected :
int itsAge ;
} ;
class Dog : public Animal
{
public :
Dog ( ) : itsWeight ( 12 ) { }
~Dog ( ) { }
void Speak ( ) const { cout << " 狗叫...\n " ; }
private :
int itsWeight ;
} ;
class Cat : public Animal
{
public :
Cat ( ) : itsWeight ( 1 ) { }
~Cat ( ) ;
void Speak ( ) const { cout << " 猫叫...\n " ; }
private :
int itsWeight ;
} ;
class Lion : public Animal
{
public :
Lion ( ) : itsWeight ( 1000 ) { }
~Lion ( ) ;
void Speak ( ) const { cout << " 狮子吼...\n " ; }
private :
int itsWeight ;
} ;
class Tigger : public Animal
{
public :
Tigger ( ) : itsWeight ( 1000 ) { }
~Tigger ( ) ;
void Speak ( ) const { cout << " 虎啸...\n " ; }
private :
int itsWeight ;
} ;
class Dragon : public Animal
{
public :
Dragon ( ) : itsWeight ( 2000 ) { }
~Dragon ( ) ;
void Speak ( ) const { cout << " 龙吟...\n " ; }
private :
int itsWeight ;
} ;
int main ( )
{
Animal *TheArray [ 6 ] ;
Animal *Ptr = 0 ;
int choice , i ;
for ( i=0 ; i <= 5 ; i++ )
{
cout << " 1. 狗 2.猫 3.狮子 4.虎 5.龙 \n" ;
cin >> choice ;
switch ( choice )
{
case ( 1 ) : Ptr = new Dog ;
break ;
case ( 2 ) : Ptr = new Cat ;
break ;
case ( 3 ) : Ptr = new Lion ;
break ;
case ( 4 ) : Ptr = new Tigger ;
break ;
case ( 5 ) : Ptr = new Dragon ;
break ;
default : Ptr = new Animal ;
break ;
}
TheArray [ i ] = Ptr ;
//在这一行加入delete Ptr ; Ptr = 0 ;出错
}
for ( i=0 ; i <= 5 ; i++ )
TheArray [ i ]->Speak ( ) ;
//在这一行加入delete Ptr ; Ptr = 0 ;也出错
return 0 ;
}
以上程序中,指针Ptr被多次调用并重新赋值,第一次调用完之后是不是应该删除指针,然后再重新将其设为空指针,在进行第二次调用,以免内存泄漏,如题中注释所示,两个地方加删除语句运行时都出错,求高手解答!!! 展开
using namespace std ;
class Animal
{
public :
Animal ( ) : itsAge ( 1 ) { }
~Animal ( ) { }
virtual void Speak ( ) const { cout << " Animal speaking...\n " ; }
protected :
int itsAge ;
} ;
class Dog : public Animal
{
public :
Dog ( ) : itsWeight ( 12 ) { }
~Dog ( ) { }
void Speak ( ) const { cout << " 狗叫...\n " ; }
private :
int itsWeight ;
} ;
class Cat : public Animal
{
public :
Cat ( ) : itsWeight ( 1 ) { }
~Cat ( ) ;
void Speak ( ) const { cout << " 猫叫...\n " ; }
private :
int itsWeight ;
} ;
class Lion : public Animal
{
public :
Lion ( ) : itsWeight ( 1000 ) { }
~Lion ( ) ;
void Speak ( ) const { cout << " 狮子吼...\n " ; }
private :
int itsWeight ;
} ;
class Tigger : public Animal
{
public :
Tigger ( ) : itsWeight ( 1000 ) { }
~Tigger ( ) ;
void Speak ( ) const { cout << " 虎啸...\n " ; }
private :
int itsWeight ;
} ;
class Dragon : public Animal
{
public :
Dragon ( ) : itsWeight ( 2000 ) { }
~Dragon ( ) ;
void Speak ( ) const { cout << " 龙吟...\n " ; }
private :
int itsWeight ;
} ;
int main ( )
{
Animal *TheArray [ 6 ] ;
Animal *Ptr = 0 ;
int choice , i ;
for ( i=0 ; i <= 5 ; i++ )
{
cout << " 1. 狗 2.猫 3.狮子 4.虎 5.龙 \n" ;
cin >> choice ;
switch ( choice )
{
case ( 1 ) : Ptr = new Dog ;
break ;
case ( 2 ) : Ptr = new Cat ;
break ;
case ( 3 ) : Ptr = new Lion ;
break ;
case ( 4 ) : Ptr = new Tigger ;
break ;
case ( 5 ) : Ptr = new Dragon ;
break ;
default : Ptr = new Animal ;
break ;
}
TheArray [ i ] = Ptr ;
//在这一行加入delete Ptr ; Ptr = 0 ;出错
}
for ( i=0 ; i <= 5 ; i++ )
TheArray [ i ]->Speak ( ) ;
//在这一行加入delete Ptr ; Ptr = 0 ;也出错
return 0 ;
}
以上程序中,指针Ptr被多次调用并重新赋值,第一次调用完之后是不是应该删除指针,然后再重新将其设为空指针,在进行第二次调用,以免内存泄漏,如题中注释所示,两个地方加删除语句运行时都出错,求高手解答!!! 展开
3个回答
展开全部
第一次循环时Ptr虽然多次调用new,但每次分配的内存指针都保存在TheArray数组中,此时相当于初始化的过程,绝对不能马上释放内存空间。
在调用Speak的时候,每次所使用的TheArray[i]就是之前依此申请并初始化的各个实例,使用过后可以释放,但delete的不是Ptr,而是TheArray[i],应该是delete TheArray[i]。因为此时Ptr不能重复的被delete,delete一个空指针是肯定会出错的,希望有用。
在调用Speak的时候,每次所使用的TheArray[i]就是之前依此申请并初始化的各个实例,使用过后可以释放,但delete的不是Ptr,而是TheArray[i],应该是delete TheArray[i]。因为此时Ptr不能重复的被delete,delete一个空指针是肯定会出错的,希望有用。
追问
请问,delete TheArray[i]之后,Ptr申请的内存也被释放了吗?是不是TheArray [ i ] = Ptr这句之后,Ptr和TheArray [ i ]是指向同一个地址的指针,只是名称不同罢了?
追答
呵呵,Ptr其实你可以看作一个临时的变量而已,用处就是初始化TheArray这个数组,这也是我们C/C++里初始化构建一个链表啊什么的常用的写法。等到初始化结束之后,Ptr每次的值虽然不一样,但是这些值肯定都保存在TheArray数组之中了。那么使用过TheArray之后,只要把TheArray里面每一个指针释放掉就不会内存泄漏,不用再担心Ptr了。
展开全部
TheArray [ i ] = Ptr ;
//在这一行加入delete Ptr ; Ptr = 0 ;出错
//这儿出错是因为后面还要访问(TheArray [ i ]->Speak ( ) ;)
}
for ( i=0 ; i <= 5 ; i++ )
TheArray [ i ]->Speak ( ) ;
//在这一行加入delete Ptr ; Ptr = 0 ;也出错
//经测试,这儿加是不会出错的。但只释放一个单元,还有其他5个单元没有释放,改成下面较好:
for ( i=0 ; i <= 5 ; i++ )
delete TheArray[i];
return 0 ;
}
//在这一行加入delete Ptr ; Ptr = 0 ;出错
//这儿出错是因为后面还要访问(TheArray [ i ]->Speak ( ) ;)
}
for ( i=0 ; i <= 5 ; i++ )
TheArray [ i ]->Speak ( ) ;
//在这一行加入delete Ptr ; Ptr = 0 ;也出错
//经测试,这儿加是不会出错的。但只释放一个单元,还有其他5个单元没有释放,改成下面较好:
for ( i=0 ; i <= 5 ; i++ )
delete TheArray[i];
return 0 ;
}
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
楼主 你好,看了你那两句话我也弄了很久,重新回顾了下东西,呵呵,我就以我浅陋的知识来说下自己的看法,说的不对不要怪我误认,哈哈,回答别人的问题是最好的学习方法~
首先你得弄清 delete 是释放 在堆上new的空间 ,堆上的空间是需要程序员来释放的,在程序执行完那个模块之后如果没有释放,操作系统是不会主动释放的,它会认为你new的那个地方还需要用,这样会造成堆上能用的空间减少,还有那个空间里的东西不会被覆盖,容易被人被人从中提取你程序的数据,大概就是你所说的内存泄漏啊(哈哈,我是这么想的,是不是真的我也不确定,最好自己在仔细研究下)
说了上面些,我觉得 把第一个 delete 去掉不要,你应该能理解了把,呵呵,还是说下自己的看法把。当你第一次new了一个空间给 ptr 的时候,它在堆上的地址可能是 x0fee23323,当你在循环中就释放它的时候,x0fee23323就又变成一块空地,当循环进行的第二次的时候,又有个new请求,就会造成 重新把 x0fee23323分配给ptr的可能,其实在这来说还是对的(有限空间的充分利用就是计算机要干的),但当你把这个相同的地址在给 数组的时候就有问题了,因为你数组里保存的就是上次new的空间(堆上)地址,这样你上一次数组所指的东西就没了~
现在说说第二个delete ,如果按你那加上的话,会只能释放最后一个new的,现在你得去升入弄清delete的意义(以下内容是个人理解,对正确与否不负责,哈哈)
delete就去释放 指针指向堆里的那块空间,而你上面的实现要完全释放new的空间,你得去一个个释放掉,可以 delete TheArray [ i ]; 要放在 循环里面;
哈哈,说完了,个人认为上面的实现不好(我也没想是不是有好的,哈哈,)
还可以继续讨论
~
先说到这里了~
首先你得弄清 delete 是释放 在堆上new的空间 ,堆上的空间是需要程序员来释放的,在程序执行完那个模块之后如果没有释放,操作系统是不会主动释放的,它会认为你new的那个地方还需要用,这样会造成堆上能用的空间减少,还有那个空间里的东西不会被覆盖,容易被人被人从中提取你程序的数据,大概就是你所说的内存泄漏啊(哈哈,我是这么想的,是不是真的我也不确定,最好自己在仔细研究下)
说了上面些,我觉得 把第一个 delete 去掉不要,你应该能理解了把,呵呵,还是说下自己的看法把。当你第一次new了一个空间给 ptr 的时候,它在堆上的地址可能是 x0fee23323,当你在循环中就释放它的时候,x0fee23323就又变成一块空地,当循环进行的第二次的时候,又有个new请求,就会造成 重新把 x0fee23323分配给ptr的可能,其实在这来说还是对的(有限空间的充分利用就是计算机要干的),但当你把这个相同的地址在给 数组的时候就有问题了,因为你数组里保存的就是上次new的空间(堆上)地址,这样你上一次数组所指的东西就没了~
现在说说第二个delete ,如果按你那加上的话,会只能释放最后一个new的,现在你得去升入弄清delete的意义(以下内容是个人理解,对正确与否不负责,哈哈)
delete就去释放 指针指向堆里的那块空间,而你上面的实现要完全释放new的空间,你得去一个个释放掉,可以 delete TheArray [ i ]; 要放在 循环里面;
哈哈,说完了,个人认为上面的实现不好(我也没想是不是有好的,哈哈,)
还可以继续讨论
~
先说到这里了~
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询