#include <iostream>
#include <string>
using String = std::string;//简化代码就不用到处写 std :: string
class Entity
{
private:
String m_Name;
public:
Entity() : m_Name("UnKnown") {}
Entity(const String& name) : m_Name(name) {}
const String& GetName() const { return m_Name; }
};
void Function()
{
int a = 2;
Entity entity = Entity("dajian"); //这里是栈 { }结束后内存就释放了
}
int main()
{
Function();
Entity entity;//无参
//Entity entity = Entity("dajian") 有参
std::cout << entity.GetName() << std::endl;
std::cin.get();
}
#include <iostream>
#include <string>
using String = std::string;//简化代码就不用到处写 std :: string
class Entity
{
private:
String m_Name;
public:
Entity() : m_Name("UnKnown") {}
Entity(const String& name) : m_Name(name) {}
const String& GetName() const { return m_Name; }
};
void Function()
{
int a = 2;
Entity entity = Entity("dajian"); //这里是栈 { }结束后内存就释放了
}
int main()
{
//Entity* e;
//{
//
// Entity entity = Entity("dajian"); // 有参
// e = &entity//第一次是正确指向的,当花括号结束后,里面的值就没了,因为是栈
// std::cout << entity.GetName() << std::endl;
//}
Entity* e;
{
Entity* entity = new Entity("dajian"); //这里是在堆上建的,调用时,这个 new Entity其实会返回一个Entity*也就是entity在堆上被分配的地址
e = entity//{}结束后依旧存在 直到自己delete后才会消失
std::cout << (*entity).GetName() << std::endl;
}
std::cin.get();
delete e;//要自己释放内存
}
上面的代码中就是分别用堆和栈来建立了一个对象,通过上面的代码我们可以总结一下堆和栈:
heap 堆:
该内存段由程序员手动调用内存管理函数(malloc/free),进行分配、释放,它的分配释放受程序员的控制,适合存储一些需要长期使用的数据。
它的大小不受限制,理论上能达到物理的上限,所以适合存储大量的数据。
该内存段无法取名字,也就是无法与标识符建立联系,必须与指针配合使用。
stack 栈:
存储的是局部变量、块变量
该内存段会随着程序的执行自动的分配(定义局部变量、块变量)、释放(函数执行完毕自动释放局部变量、块变量),虽然使用比较方便,但它的释放不受程序控制,长期使用的数据不能存储在栈内存中。
该内存的大小有限,在终端执行: ulimit -s 可以查看当前系统栈内存的使用上限,我们使用虚拟机ubuntu的栈内存使用上限是8192kb,一旦超过这个限制就会产生段错误。可以使用ulimit -s <size> 命令设置栈内存的使用上限。