C 中动态内存分配引发问题的解决方案

2008-02-23 05:24:57来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

 假设我们要研发一个String类,他能够方便地处理字符串数据。我们能够在类中声明一个数组,考虑到有时候字符串极长,我们能够把数组大小设为200,但一般的情况下又无需这么多的空间,这样是浪费了内存。对了,我们能够使用new操作符,这样是十分灵活的,但在类中就会出现许多意想不到的问题,本文就是针对这一现象而写的。现在,我们先来研发一个Wrong类,从名称上看出,他是个不完善的类。的确,我们要刻意地使他出现各种各样的问题,这样才好对症下药。好了,我们开始吧!

  Wrong.h:

#ifndef WRONG_H_
#define WRONG_H_
class Wrong
{
private:
char * str; //存储数据
int len; //字符串长度

public:
Wrong(const char * s); //构造函数
Wrong(); // 默认构造函数
~Wrong(); // 析构函数
friend ostream & operator<<(ostream & os,const Wrong& st);
};
#endif

Wrong.cpp:

#include <iostream>
#include <cstring>
#include "wrong.h"
using namespace std;
Wrong::Wrong(const char * s)
{
len = strlen(s);
str = new char[len 1];
strcpy(str, s);

}//拷贝数据

Wrong::Wrong()
{
len =0;
str = new char[len 1];
str[0]='\0';

}

Wrong::~Wrong()
{
cout<<"这个字符串将被删除:"<<str<<'\n';//为了方便观察结果,特留此行代码。
delete [] str;
}

ostream & operator<<(ostream & os, const Wrong & st)
{
os << st.str;
return os;
}

test_right.cpp:

#include <iostream>
#include <stdlib.h>
#include "Wrong.h"
using namespace std;
int main()
{
Wrong temp("天极网");
cout<<temp<<'\n';
system("PAUSE");
return 0;
}

  运行结果:

  天极网

  请按任意键继续. . .

  大家能够看到,以上程式十分正确,而且也是十分有用的。可是,我们不能被表面现象所迷惑!下面,请大家用test_wrong.cpp文档替换test_right.cpp文档进行编译,看看结果。有的编译器可能就是根本不能进行编译!

  test_wrong.cpp:

#include <iostream>
#include <stdlib.h>
#include "Wrong.h"
using namespace std;
void show_right(const Wrong&);
void show_wrong(const Wrong);//注意,参数非引用,而是按值传递。
int main()
{
Wrong test1("第一个范例。");
Wrong test2("第二个范例。");
Wrong test3("第三个范例。");
Wrong test4("第四个范例。");
cout<<"下面分别输入三个范例:\n";
cout<<test1<<endl;
cout<<test2<<endl;
cout<<test3<<endl;
Wrong* wrong1=new Wrong(test1);
cout<<*wrong1<<endl;
delete wrong1;
cout<<test1<<endl;//在Dev-cpp上没有任何反应。
cout<<"使用正确的函数:"<<endl;
show_right(test2);
cout<<test2<<endl;
cout<<"使用错误的函数:"<<endl;
show_wrong(test2);
cout<<test2<<endl;//这一段代码出现严重的错误!
Wrong wrong2(test3);
cout<<"wrong2: "<<wrong2<<endl;
Wrong wrong3;
wrong3=test4;
cout<<"wrong3: "<<wrong3<<endl;
cout<<"下面,程式结束,析构函数将被调用。"<<endl;
return 0;
}
void show_right(const Wrong& a)
{
cout<<a<<endl;
}
void show_wrong(const Wrong a)
{
cout<<a<<endl;
}


  运行结果:

  下面分别输入三个范例:

  第一个范例。
  第二个范例。
  第三个范例。

  第一个范例。

  这个字符串将被删除:第一个范例。

  使用正确的函数:
  
  第二个范例。
  第二个范例。

  使用错误的函数:
  第二个范例。

  这个字符串将被删除:第二个范例。

  这个字符串将被删除:?=
  ?=

  wrong2: 第三个范例。
  wrong3: 第四个范例。

  下面,程式结束,析构函数将被调用。

  这个字符串将被删除:第四个范例。

  这个字符串将被删除:第三个范例。

  这个字符串将被删除:?=

  这个字符串将被删除:x =

  这个字符串将被删除:?=

  这个字符串将被删除:

  现在,请大家自己试试运行结果,或许会更加惨不忍睹呢!下面,我为大家一一分析原因。 假设我们要研发一个String类,他能够方便地处理字符串数据。我们能够在类中声明一个数组,考虑到有时候字符串极长,我们能够把数组大小设为200,但一般的情况下又无需这么多的空间,这样是浪费了内存。对了,我们能够使用new操作符,这样是十分灵活的,但在类中就会出现许多意想不到的问题,本文就是针对这一现象而写的。现在,我们先来研发一个Wrong类,从名称上看出,他是个不完善的类。的确,我们要刻意地使他出现各种各样的问题,这样才好对症下药。好了,我们开始吧!

  Wrong.h:

#ifndef WRONG_H_
#define WRONG_H_
class Wrong
{
private:
char * str; //存储数据
int len; //字符串长度

public:
Wrong(const char * s); //构造函数
Wrong(); // 默认构造函数
~Wrong(); // 析构函数
friend ostream & operator<<(ostream & os,const Wrong& st);
};
#endif

Wrong.cpp:

#include <iostream>
#include <cstring>
#include "wrong.h"
using namespace std;
Wrong::Wrong(const char * s)
{

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇: C 编程中的四个调试小技巧

下一篇: 利用C 编写一个猜字游戏