匪夷所思的内存错误

来源:百度知道 编辑:UC知道 时间:2024/06/17 05:08:49
以下代码模拟了string类的部分功能。但在VC编译器上运行后出现内存错误。puzzling……

#include <iostream>
using namespace std;

class String
{
public:
String();
String(const char * const);
String(const String &);
~String();

char * GetString() const {return itsString;}
int GetLen() const {return itsLen;}
String & operator=(const String &);
friend ostream & operator<<(ostream &,String &);
void SetString(const char *);
private:
String(int len);
char *itsString;
int itsLen;
};

String::String()
{
itsLen=0;
itsString=new char[1];
itsString[0]='\0';
}

String::String(int len)
{
itsString=new char[len+1];
for(int i=0;i<=len;i++)
itsString[i]='\0';
itsLen=len;
}

String::String(const char *const p)
{
int i;
for(i=0;p[i];i++);

void String::SetString(const char *s)
{
int i;
for(i=0;s[i];i++);
itsLen=i;

String temp(itsLen);

for(i=0;s[i];i++)
temp.itsString[i]=s[i];
temp.itsString[i]='\0';

*this=temp;
}
这个函数把一个局部变量的地址赋给了this指针,但函数返回后局部变量的内存区域被释放了,this指向的内存不可预料.另外对等号的重载也有问题,没有删除原来的内存造成了内存泄漏.整个程序还应该仔细斟酌.

修改答复:
不好意思,上面说的没有仔细斟酌.不过对=的重载确实出现了问题.=是对左值的更新,更新操作一般遵循先删除再重新分配的原则.你的程序中没有先删除this->itsString指向的内存,而是继续使用这一块内存,并且用新的字符数组改写这一内存的内容,那么有一个问题就是可能越界.你在main函数里面调用stringThree.SetString("I'm a student."),而stringThree原来的内容为空,其长度小于"I'm a student.",这样使用了=以后,新的字符串越过了stringThree.itsString指向的内存的边界.经实验,如果更新的字符串长度小于原来,比如定义stringThree用以下语句:String stringThree("aaaaaaaaaaaaaaaaaaa"); 那么程序可以正常执行.正确的改法是把等号重载改成下面这样,这样就没有问题了:
String & String::operator=(const String &rhs)
{
if(this==&rhs)
return *this;

//增加以下两句.
delete[] itsString;
itsString=