程序崩溃的原因有两个:
一是析构函数里name指针的释激做放不正确,new[] 对应的释放方式是: delete []
所以析构函数应该这样定义:
~Person{}
{
delete [] name
}
二是因为你没有定义类的复制构造函数和赋值 *** 作符,使得编译器使用默认的复制构造函数和赋值 *** 作符
Person a("张小松",21),b=a,c
c=b
b = a 是要使用复制构造函数的,默认的复制构造函数使得b的name成员指向a对象的指针地址
c = b 调用了默认赋值 *** 作符,使得c的name成员指向b对象的指针地址
由上可知:你的程序使得a,b,c对象的name成员指向同一个内存,这样程序在结束的时候释放各个对象,对同一个内存地址释放了3次,肯定会崩溃
你必须再定义一个复制构造函数和赋值 *** 作符,使用深度复制,使得各个对象name成员指向自己独有的内存地址,定义如下:
Person(const Person &p) //复制构造函数
{
name = new char[strlen(p.name) + 1]
strcpy(name, p.name)
age = p.age
}
Person&operator=(const Person&p) //赋值 *** 作符
{
if (this == &p)//避免自圆悉己给自己赋值
{
return *this
}
delete [] name//先释放左边对象的内存空间
name = new char[strlen(p.name) + 1]
strcpy(name, p.name)
age = p.age
return *this
}
另外,这样以后程序还是会崩溃,原因是因为main函数中定义的c对象,是调用一个未给name分配内存空间的构造函数,即 :
Person(){}
这样,你在将b赋值给c时,(c = b),调用赋值 *** 作符,先执行了释放c内存的 *** 作,未分配就释放,肯定出错,解决办法是将构造函数统一分配内存,修改如下:
Person()
{
name = new char[1]
name[0] = '\0'
}
或者修改如下:
Person()
{
name = NULL
}
这样,整个程序如下:
#include<iostream>
#include<string>
using namespace std
class Person
{
char *name
int age
public:
Person(){name = NULL}
Person(char *n,int a)
{
name=new char[strlen(n)+1]
strcpy(name,n)
age=a
}
Person(const Person&p)
{
name = new char[strlen(p.name) + 1]
strcpy(name, p.name)
age = p.age
}
Person&operator=(const Person&p)
{
if (this == &p)
{
return *this
}
delete [] name
name = new char[strlen(p.name) + 1]
strcpy(name, p.name)
age = p.age
return *this
}
~Person()
{
delete [] name
}
void print()
{
cout<<name<<'\t'<<age<<endl
}
}
void main()
{
Person a("张小松"明腔衡,21), b = a, c
c = b
c.print()
}
这种情况叫做 runtime error (运行时错误)。
在 Windows 碧昌7 上这样提示:
在 Windows XP 上这样提示:
runtime error (运行时错误)就是程序运行到一半,程序就崩溃了。
比如说:
①除以零
②数组越界:int a[3] a[10000000]=10
③指针越兆搭界:int * p p=(int *)malloc(5 * sizeof(int)) *(p+1000000)=10
④使用已经释放的空间:int * p p=(int *)malloc(5 * sizeof(int))free(p) *p=10
⑤数组开得太大,超悔猜扒出了栈的范围,造成栈溢出:int a[100000000]
按照上边的方法可以获得一个windows系岁游配统监磨逗控多进程的例子,使用WaitForMultipleObject(...:)在实际工作中,我本人一般是去读系统进程表,发现没有了就create一个,比较笨的办法乎指,不过很好用,而且很容易移植,呵呵。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)