一.对于在类内中定义:
首先有个MyString类
#include<iostream>
#include<string>
#pragma warning(disable:4996)
using namespace std;
class MyString {
public:
MyString();
~MyString() {
cout << "调用析构函数";
delete[]pname;
};
MyString(char* c); //析构函数
char * strcpy(char* s1,const char* s2);
private:
int size;
char* pname=NULL;
};
MyString::MyString(char* c) { //定义析构函数
pname = new char[strlen(c) + 1];
if (pname != NULL) strcpy(pname, c);
size = 0;
}
char *MyString::strcpy(char* s1, const char* s2) { //定义strcpy函数
s1 = new char[strlen(s2) + 1];
if (s1 != NULL) strcpy(s1, s2);
return s1;
}
int main() {
char c[] = "China";
char d[] = "Chinese";
MyString str2(c);
cout<<str2.strcpy(c, d)<<endl;
return 0;
}
代码段中的两个函数均采用相同的方法动态分配内存。但对于析构函数,采用了动态分配内存的方法初始化,运行时没有出现错误,但对于成员函数char *MyString::strcpy(char* s1, const char* s2),却会因动态分配内存那条语句出现问题。
这是为什么呢
原因可能是:
1. 在调用对象的成员函数时,会在成员函数的形参列表中增加一个指向当前对象的this指针。
故当执行函数体中strcpy(s1,s2)时,实际上为执行this->strcpy(s1,s2)
执行s1 = new char[strlen(s2) + 1];时s1动态分配得到一个内存。执行到this->strcpy(s1,s2)时;此时程序会跳转到再执行该(char *MyString::strcpy(char* s1, const char* s2))函数,再次为s1动态分配一个内存,然后又会执行到this->strcpy(s1,s2)。这样重复以上操作,又为s1分配一个内存(原来分配的内存未释放,只是s1指向改变),一直嵌套循环下去,导致stack overflow.
2. 编译器可能会混淆是调用函数库中的strcpy函数还是自定义的strcpy函数(多见与非类内成员函数,如下面的第二点)
解决方法很简单:
只需修改该函数名就可以了,如修改为char* copy(char* s1, const char* s2);
二.对于非类内成员函数
#include<iostream>
using namespace std;
#define NULL 0
#pragma warning(disable:4996)
using namespace std;
char*strcpy(char* s1, const char* s2) {
s1 = new char[strlen(s2) + 1];
if (s1 != NULL) strcpy(s1, s2);
return s1;
}
int main() {
char c[] = "China";
char d[] = "ShenZhou";
cout<<strcpy(c, d);
return 0;
}
产生的错误与可能的原因与上面相同,解决方法也是一样的。
以上原因仅为笔者看法,可能并不够准确,如有错误,望指出!
(第二篇文章!!!)