char *p = new char[5];
strcpy(p, "aaaaaaa");
delete[] p;
调用以上代码将导致程序崩溃/不稳定
从逻辑上看,从堆中申请内存并将其地址赋给p后,拷贝函数传递了超出上限的字符数,若此时堆中有空闲多余空间,则申请的内存是连续的,得以成功复制;若没有连续的空间,则从堆中另一处开辟空间,则内存是不连续的。
问题的关键出在delete,将其比作堆栈,由于设置的栈大小为5,但压入了7个字符,又由于仍成功分配了空间,所以在不调用delete函数时一切正常,当执行delete函数时,将导致出栈后的栈指针不为栈底,将导致程序出错(还有未释放的内存)。
来看这样一段代码:
class Cow
{
char name[20];
char *hobby;
double weight;
public:
Cow(const char *nm, const char *ho, double wt);
~Cow();
};
Cow::Cow(const char *nm, const char *ho, double wt)
{
strcpy(name, nm);
hobby = new char[strlen(ho)];
strcpy(hobby, ho);
weight = wt;
}
Cow::~Cow()
{
delete[] this->hobby;
// std::cout << "Bye!";
}
错误的使用了strlen(ho)导致由new申请的内存不够,在strcpy函数中中出现越界,但程序依然会继续运行(内存成功分配),直到析构函数调用时,发现栈未空,程序出错。
解决办法:使用string类,使用strcpy_s函数