关于动态内存的问题

hasagiiiii 2010-06-28 10:56:37
#include <iostream>

using namespace std;

class String
{
public:
String( const char * = 0 );
String& operator=(const char*);

private:
int _size;
char *_string;
};

String& String::operator = (const char *pi)
{



cout<<"haha"<<endl;
system("pause");
_size=0;
const char* pt=pi;
while(*pt++)
_size++;
_string=new char[_size+1];
char *str=_string;
while(*str++=*pi++);

return *this;
}

String::String(const char *pi)
{
if(!pi)
{
_size=0;
_string=0;
}
else
{
_size=0;
const char *pt=pi;
while(*pt++)
_size++;

cout<<_size<<endl;

_string=new char[_size];

char *st = _string;

while(*st++ = *pi++);

delete []_string;
}
}


void main()
{


String ab="hello,the world";
char *c="gogogoog";
ab = c;
}


请问错在哪里?我把构造函数里的delete []_string或者while (*st++ = *pi++); 去掉就没错了。为什么?先别在程序上挑毛病,我想知道这里为什么会有错,申请了动态内存,然后释放掉有什么错呢?
...全文
243 19 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
hasagiiiii 2010-07-02
  • 打赏
  • 举报
回复
谢谢!
livedrm 2010-06-30
  • 打赏
  • 举报
回复
构造函数中
_string=new char[_size];
应该为
_string=new char[_size+1];
否则
while(*st++ = *pi++);
最后一步循环在未申请的内存赋值,属于未定义行为,可能在别的系统上不会出错,看运气。所以O啦
doublemoon 2010-06-30
  • 打赏
  • 举报
回复
using namespace std;

class String
{
public:
String( const char * = 0 );
String& operator=(const char*);

private:
int _size;
char *_string;
};

String& String::operator = (const char *pi)
{
cout<<"haha"<<endl;
system("pause");
_size=0;
const char* pt=pi;
while(*pt++)
_size++;
_string=new char[_size+1];
char *str=_string;
while(*str++=*pi++);

return *this;
}

String::String(const char *pi)
{
if(!pi)
{
_size=0;
_string=0;
}
else
{
_size=0;
const char *pt=pi;
while(*pt++) //此处算出来的大小,不包括'\0'
_size++;

cout<<_size<<endl;

_string=new char[_size+1]; //由于不包括'\0',所以你new出来的的大小需要加1

char *st = _string;

while( *st++ = *pi++) //由于你没有加1,所以此处访问越界了
;

delete []_string; //删除一个越界指针,肯定会出错的
}
}


void main()
{
String ab="hello,the world";
char *c="gogogoog";
ab = c;
}
doublemoon 2010-06-30
  • 打赏
  • 举报
回复
[code=C/C++]using namespace std;

class String
{
public:
String( const char * = 0 );
String& operator=(const char*);

private:
int _size;
char *_string;
};

String& String::operator = (const char *pi)
{
cout<<"haha"<<endl;
system("pause");
_size=0;
const char* pt=pi;
while(*pt++)
_size++;
_string=new char[_size+1];
char *str=_string;
while(*str++=*pi++);

return *this;
}

String::String(const char *pi)
{
if(!pi)
{
_size=0;
_string=0;
}
else
{
_size=0;
const char *pt=pi;
while(*pt++) //此处算出来的大小,不包括'\0'
_size++;

cout<<_size<<endl;

_string=new char[_size+1]; //由于不包括'\0',所以你new出来的的大小需要加1

char *st = _string;

while( *st++ = *pi++) //由于你没有加1,所以此处访问越界了
;

delete []_string; //删除一个越界指针,肯定会出错的
}
}


void main()
{
String ab="hello,the world";
char *c="gogogoog";
ab = c;
}code]
huhacn 2010-06-30
  • 打赏
  • 举报
回复
对于动态分配的内存,越界操作后,再调用delete[]操作,就会报错
楼主的错误即下面的错误:
char *p = new char[1024];
memset(p, 0, 1024+1);//while(*st++ = *pi++)
delete []p;
Zeilone 2010-06-30
  • 打赏
  • 举报
回复
new出来的空间大小不对,还要加上字符串最后的结束符
比如你的字符串是10个字符
你只new出来10个字节的空间
while(*st++ = *pi++)时,到最后的结束符会写到第十一个字节
所以就会出现访问错误
mofeellassie 2010-06-30
  • 打赏
  • 举报
回复
改为这样就行了while(*st++ = *pi++ && *pi !=NULL);
确实已经越界了
winterlc 2010-06-30
  • 打赏
  • 举报
回复
代码问题很多呀,拿出来根本没法用。
delete []_string; _string做为成员变量,delete后要置为NULL。而且就算你在这里删除,_size的值还是大于0的。
然后其他问题大家都提过了
hasagiiiii 2010-06-29
  • 打赏
  • 举报
回复
只有5楼说得靠谱,我想知道的是为什么错。谢谢了。而7楼,我不是说我要把那句注释掉,然后继续用这个程序,我的意思是错误可能就在那句上,我想弄明白为什么注释掉那句就不会出错,5楼就说的清楚了,因为那句已经越界访问了。
zhoulingj 2010-06-29
  • 打赏
  • 举报
回复
while(*st++ = *pi++);

的确是越界了,如果你想根据*pi==0去让循环结束,就显示的写出来嘛,不然看起来也麻烦。
ForestDB 2010-06-29
  • 打赏
  • 举报
回复
帮顶。
cattycat 2010-06-28
  • 打赏
  • 举报
回复
delete []_string;
应该放在析构函数中,构造函数怎么能delete呢。
pengzhixi 2010-06-28
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 lijiantao923 的回复:]
引用 1 楼 pengzhixi 的回复:
_string=new char[_size];

char *st = _string;

while(*st++ = *pi++);

delete []_string;//你这里就将内存释放了,那后面就不能对_string所指的内存进行操作了。


不是这个问题,你试下把while(*st++ = *pi++);这句注释掉,就不……
[/Quote]
如果你打算考人品吃饭的话,你大可以这么用。至于while(*st++ = *pi++);你完全可以使用strncpy
yunyun1886358 2010-06-28
  • 打赏
  • 举报
回复
这样:

#include <iostream>

using namespace std;

class String
{
public:
String( const char * = 0 );
String& operator=(const char*);

private:
int _size;
char *_string;
};

String& String::operator = (const char *pi)
{



cout<<"haha"<<endl;
system("pause");
_size=0;
const char* pt=pi;
while(*pt++)
_size++;
_string=new char[_size+1];
char *str=_string;
while(*str++=*pi++);

return *this;
}

String::String(const char *pi)
{
if(!pi)
{
_size=0;
_string=0;
}
else
{
_size=0;
const char *pt=pi;
while(*pt++)
_size++;

cout<<_size<<endl;

_string=new char[_size + 1];

char *st = _string;

while(*st++ = *pi++);

//delete []_string;
}
}


void main()
{


String ab="hello,the world";
char *c="gogogoog";
ab = c;
}
yunyun1886358 2010-06-28
  • 打赏
  • 举报
回复

String::String(const char *pi)
{
if(!pi)
{
_size=0;
_string=0;
}
else
{
_size=0;
const char *pt=pi;
while(*pt++)
_size++;

cout<<_size<<endl;

_string=new char[_size];

char *st = _string;

while(*st++ = *pi++); // 这一句内存访问越界了,将_string后面一个字节的内存置为了'\0'

delete []_string;
}
}
hasagiiiii 2010-06-28
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 whg01 的回复:]
_string=new char[_size]; 应该是_string=new char[_size+1];要把字符串结束标记计算在内。
char *st = _string; st指向了_string指向的地址,所以delete []_string;这句会导致st指向的内存被释放。
释放之后,就不要再使用了。
[/Quote]

不是这个问题,你试下把while(*st++ = *pi++);这句注释掉,就不会有错!
hasagiiiii 2010-06-28
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 pengzhixi 的回复:]
_string=new char[_size];

char *st = _string;

while(*st++ = *pi++);

delete []_string;//你这里就将内存释放了,那后面就不能对_string所指的内存进行操作了。
[/Quote]

不是这个问题,你试下把while(*st++ = *pi++);这句注释掉,就不会有错!
whg01 2010-06-28
  • 打赏
  • 举报
回复
_string=new char[_size]; 应该是_string=new char[_size+1];要把字符串结束标记计算在内。
char *st = _string; st指向了_string指向的地址,所以delete []_string;这句会导致st指向的内存被释放。
释放之后,就不要再使用了。
pengzhixi 2010-06-28
  • 打赏
  • 举报
回复
_string=new char[_size];

char *st = _string;

while(*st++ = *pi++);

delete []_string;//你这里就将内存释放了,那后面就不能对_string所指的内存进行操作了。

65,186

社区成员

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

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