自定义的一个string类,但不知道哪里出现了一个问题

密斯刘 2009-08-14 12:57:20
如下面的代码 自己定义的一个String类,记得在学校机房调试的时候到了程序运行的最后面弹出了一个错误对话框,下面有三个按钮的那种“终止、忽略、取消” 具体信息我忘了 因为我在 自己电脑上面调试的时候 并没有弹出那个错误对话款,而是到最后面就不动了 我截了图 大家可以看下 工程自己建立以下就是了 一共有三个文件 main.cpp string.cpp string.h

代码有点长 可能发帖贴不下来 所以我放到博客里面去了
地址是
http://blog.csdn.net/vb2010/archive/2009/08/14/4446153.aspx

希望大家看看 帮个忙 我实在找不出是哪里出了问题
...全文
145 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
密斯刘 2009-08-14
  • 打赏
  • 举报
回复
先顶一下 免得沉下去了
密斯刘 2009-08-14
  • 打赏
  • 举报
回复
谢谢 我知道了 原来就是一个小小的越界错误 至于其他方面 我暂时不管了 还有那个内存泄露问题 我是准备处理的 但是……算了 还是不要闲麻烦 改一下好些
最后 特别感谢steedhorse(晨星) 你考虑非常周全 … … … … 膜拜你 呵呵呵 花了我一百分啊 &………………………………
coverallwangp 2009-08-14
  • 打赏
  • 举报
回复

String::String( const char* str )
{
//add code here..
//要判断原字符串是否为空
if(str == NULL)
{
mData = new char[1];
*mData = '\0';
mLength = 0;
}
else
{
int buff_size = strlen(str);
mLength = buff_size;
mData = new char[buff_size + 1];
//strncpy()比strcpy()更安全
strncpy(mData,str,buff_size);
mData[buff_size] = '\0'; //此处去掉+1,只改这一个地方就可以了
}
}
晨星 2009-08-14
  • 打赏
  • 举报
回复
void String::reverse()   
{
//add code here...
String temp(*this);
int i;
mData = new char[temp.mLength + 1];
mLength = temp.mLength;
for(i = 0; i < temp.mLength; ++i)
{
mData[i] = temp.mData[temp.mLength - i - 1];
}
mData[mLength] = '\0';
}

——这个大体看了一下,好像没啥错。但反转一个字符串完全可以直接在原字符串上进行,不必使用临时缓冲区。
晨星 2009-08-14
  • 打赏
  • 举报
回复
String String::operator +(const String &str )   
{
//add code here...
//这里需要注意加运算并不改变操作数
String temp(*this);
int i;
temp.mData = new char[this->mLength + str.mLength + 1];

for(i = 0; i < this->mLength; ++i)
{
temp.mData[i] = this->mData[i];
}

for(i = 0; i < str.mLength; ++i)
{
temp.mData[this->mLength + i] = str.mData[i];
}
temp.mData[this->mLength + str.mLength] = '\0';
temp.mLength = this->mLength + str.mLength;

return temp;
}

——这个一开始不必要String temp(*this); 直接构造一个空的即可,否则还是有内存泄露。
mstlq 2009-08-14
  • 打赏
  • 举报
回复

String::String( const char* str )
{
//add code here..
//要判断原字符串是否为空
if(str == NULL)
{
mData = new char[1];
*mData = '\0';
mLength = 0;
}
else
{
int buff_size = strlen(str);
mLength = buff_size;
mData = new char[buff_size + 1];
//strncpy()比strcpy()更安全
strncpy(mData,str,buff_size);
mData[buff_size + 1] = '\0';//此处越界访问,应为mData[buff_size] = '\0'
}
}
晨星 2009-08-14
  • 打赏
  • 举报
回复
const String::size_t & String::size() const  
{
//add code here...
return mLength;
}

——整数类型没必需使用引用返回。
晨星 2009-08-14
  • 打赏
  • 举报
回复
void String::copyfromotherstring( const String& str )   
{
//add code here...
for(int i = 0; i < str.mLength; ++i)
{
mData = new char[1];
this->mData = str.mData;
}
this->mLength = str.mLength;
}

———这个明显不对,每次循环都申请一个新的字节,然后旧的就白白扔了不管了?
也应该像其拷贝构造函数那样,一次申请所有的空间,然后再拷贝。
晨星 2009-08-14
  • 打赏
  • 举报
回复
String& String::operator =(const String & str )   
{
copyfromotherstring(str);
return *this;
}

——没有释放原来的空间,虽然不会引起内存错误,但会导致内存泄露。
另外,operator=最好检查一下自赋值,这样能更健壮一些,防止别人写a = a;的时候出现严重问题。
lori227 2009-08-14
  • 打赏
  • 举报
回复
void String::copyfromotherstring( const String& str )
{
//add code here...
for(int i = 0; i < str.mLength; ++i)
{
mData = new char[1]; //这里在外面new
this->mData = str.mData; //这个用strncpy
}
this->mLength = str.mLength;
}


你这个new 是错误的`~~ 在循环外面new一次就OK得~~注意长度~`

还有就是 你每次new之前需要delete以前new出来的 否则 内存泄漏了~~
晨星 2009-08-14
  • 打赏
  • 举报
回复
String::String( const char* str )   
{
//add code here..
//要判断原字符串是否为空
if(str == NULL)
{
mData = new char[1];
*mData = '\0';
mLength = 0;
}
else
{
int buff_size = strlen(str);
mLength = buff_size;
mData = new char[buff_size + 1];
//strncpy()比strcpy()更安全
strncpy(mData,str,buff_size);
mData[buff_size + 1] = '\0';
}
}
——最后一句,不应该加1。
chenzhp 2009-08-14
  • 打赏
  • 举报
回复
结构很清晰啊,单步debug一下
KWHOK 2009-08-14
  • 打赏
  • 举报
回复
单步调试吧,
mstlq 2009-08-14
  • 打赏
  • 举报
回复
string.cpp string.h

这两个文件最好请改改名字……
省得和系统的库文件冲突^_^
晨星 2009-08-14
  • 打赏
  • 举报
回复
直接从第一句单步跟踪就是了。

64,651

社区成员

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

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