c++对象内存分配的问题,如何确定在堆上还是在栈上?

c++中对象内存放堆上还是在栈上是不是根据对象实例化的方法,如:
A a; //在栈中分配内存
A * a = new A(); //动态内存分配,在堆上

要是这样,如果我尽量不用指针的话(这样程序风格似乎更加清晰一些),那是不是对象都分配到栈上了?这有什么弊端吗?栈的空间是不是很有限?是不是为了栈空间的问题我们必须尽量多用new分配内存呢?类成员是不是也要多用指针呢?

7个回答

经过昨晚大家的热心帮助,对该问题的疑问已经烟消云散,谢谢大家!在此总结一下:
“非new的对象在栈中分配,new的对象在堆中分配” 这句话是没有问题的。而这个
class A {
public:
A(void) :v1(10) { v1[0] = "abc"; }
vector v1;
};
只是一个类的定义,还没有实例化,是不涉及到任何内存分配的,根本不适用于内存分配原则。就算实例化后,v1变量只是a对象的一个成员变量,它在堆上还是在栈上是由a对象的分配方式决定的,而不是由其声明方式决定的。

用new分配的一个很重要的原因不仅是在堆上分配控件,而是说需要分配多少空间在编写程序的时候不确定。特别是数组,如果要不用动态分配,我们必须在开发的时候估算数组大小的上限,以防不够用。
但是多半这么做是浪费的。
堆栈的确有容量的限制,特别是当你递归调用的时候,对堆栈使用越多,你的递归层数就越少。
但是堆栈的好处是,它会自动分配/清栈,而动态分配你必须时刻小心,及时释放,以免内存泄漏。

我说的是编译时和运行时。

比如说,你的程序是这个逻辑:
请输入数组的大小:
xxx
请输入每个元素
x
x
x
结果是
xxx
显然,这里对于运行时,我们可以知道大小,但是对于编译时,我们就不知道大小。

zhuwt2008
zhuwt2008 能告诉我出处吗?
5 年多之前 回复
zhuwt2008
zhuwt2008 但是我没有看到说c++通过看编译时程序是否知道对象大小来决定放在堆上还是栈上的
5 年多之前 回复

多年前,我看了32bit windows的内存分配,栈的默认大小是2MB,而堆应该是2GB。
在栈上访问内存理论上来讲效率高一些,但是大规模数据的话,不够用。

堆与栈都有不同的使用情况,对于动态数据,比较大的结构体,类,我们建议使用new,放在堆中,栈中主要还是改局部变量和函数调用栈使用的,栈的大小 是有限的!
动态分配内存时可以使用智能指针来包装,使用RAII原则,基本上可以解决内存泄漏问题。

fengfei_2010
fengfei_2010 回复zhuwt2008: 对于Windows32位操作系统栈一般是1M,可以自己定义一个临时数组,比如数组 int a[259024],我的机子最大只能分配259024个整形在栈中,不到1M,262144个整形是1M。
5 年多之前 回复
zhuwt2008
zhuwt2008 是啊,我觉得这就有问题了,如果我有一个自定义类型中有一个成员:vector<string> v1;那么v1应该是放在栈上的,如果v1很大,那是不是成为程序潜在的问题呢?
5 年多之前 回复
fengfei_2010
fengfei_2010 回复zhuwt2008: 不过放字符串常量的内存另当别论,字符串常量是放在静态内存区,和程序编码放在一起。
5 年多之前 回复
fengfei_2010
fengfei_2010 回复fengfei_2010: 不过放字符串常量的内存另当别论,字符串常量是放在静态内存区,和程序编码放在一起。
5 年多之前 回复
fengfei_2010
fengfei_2010 回复zhuwt2008: 是的。根据C++语法衡量是在栈上分配空间还是在堆上分配空间的一个原则是是否是new申请的空间。
5 年多之前 回复
zhuwt2008
zhuwt2008 嗯,RAII原则确实应该采纳,但是我仍然很想弄明白那些基本的语法,c++是如何处理的,能告诉我吗?vector<string> v1,这一句是不是将v1分配在栈上呢?
5 年多之前 回复
zhuwt2008
zhuwt2008 嗯,RAII原则确实应该采纳,但是我仍然很想弄明白那些基本的语法,c++是如何处理的,能告诉我吗?vector<string> v1,这一句是不是将v1分配在栈上呢?
5 年多之前 回复

晕,我没有这么说,编译器会判断和决定如何分配内存。你定义的局部变量都在堆栈上,而malloc new的都在堆上,这是固定的。

栈上分配快,但是空间比较小,而且局部变量等数据在栈上,它会自动释放,而堆的生命期受你控制,可以分配的空间大

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐