堆空间指向栈空间的问题
堆空间指向栈空间是危险的,比如,在函数调用结束,栈空间会自动回收,而我们继续使用new出来的对象,对象的属性可能指向一块已经回收掉的栈空间。
以下面为例,初始化化列表时如果写成
Car(int price = 0,const char * name = NULL):m_price(price),m_name(name)
就很糟糕,因为name是一个局部变量,如果在一个函数中创建了Car对象,执行完函数就会销毁name。当我们继续使用Car这个对象,由于name已经销毁,指针m_name则会访问到不该访问的栈空间内存。
正确做法如下:在对象里面new一个空间出来,存放来自name的内容,然后在析构函数中delete掉。
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;
class Car
{
private:
int m_price;
char * m_name;
public:
Car(int price = 0,const char * name = NULL):m_price(price)
{
if (name == NULL) return;
//申请新的堆空间
m_name = new char[strlen(name) + 1]{};
strcpy(m_name, name);
cout << "price = " << m_price << endl;
cout << "name = " << m_name << endl;
}
~Car()
{
if (m_name == NULL) return;
delete[] m_name;
m_name = NULL;
}
};
int main()
{
int price = 300000;
const char *name = "bmw";
Car *car = new Car(price, name);
return 0;
}
Q:为什么m_price(price)就可以,而m_name(name)就不行?
A:m_price在堆空间,m_name也在堆空间,m_price(price)会把price内容放进m_price,用到的数据都在堆空间操作,而m_name(name)是m_name指向name,用到的数据直接在栈空间操作并不会拷贝到堆空间来