问题描述
- c++语句vector<string> v1;v1对象一定放在栈中吗?
-
如果有这么一句程序:vector v1;v1是分配在栈上吗?不要小看这个问题,书里的基础概念我已经读了几遍,但是这个迷惑仍然不能解决,要不我就不用花时间上网来问了,期望能有高手指教,
按一般的理解,大概是这样:
C++对象存放在堆上还是栈上由你的代码控制,用new申请的对象放到堆上(new是没有重载的),否则放在栈上,比如
class A {};
A a; //A的对象在栈中分配内存
A * a = new A(); //A的对象在堆上分配内存上面应该是没有疑问的,可是看下面代码:
#include
#include
using namespace std;class A {
public:
A(void) :v1(10) {v1[0]="abc";}
vector v1;
};A *getA()
{
A * a = new A; // 没重载 new 操作符的。
return a;
}int main()
{
A *b = getA();
string s1("ABCDEFHIMDI");
printf(b->v1[0].data());
if(b->v1.size()==10) printf(":ok");return 0;
}
按上面逻辑,上面代码中v1应该在栈上,而“a 指向的内存空间(new A)”应该在堆上,当我调用完getA函数之后,函数getA的栈空间会被自动回收,那么获取的对象指针(即b)所指的对象的成员v1就指向无意义的内存空间(已被回收的栈空间)了,按这个逻辑,似乎都是确切无疑的推理,那么程序应该会出问题,可是程序能正常运行输出“abc:ok”,为什么呢?
解决方案
v1不一定在堆栈上,在不在堆栈上要看它属于的那个A的实例对象在不在堆栈上。
你把问题想复杂了。new和malloc的在堆上,局部变量在堆栈上。如果一个对象在堆栈上,它的成员也在堆栈上,如果一个对象在堆上,它的成员都在堆上。
解决方案二:
学编程有时候需要一点灵性。这我觉得并不难理解。你问来问去不如自己仔细想想。
解决方案三:
1、vector v1 并没有给他指定vector中的数据类型 2、getA函数的功能是动态申请一块内存类型为A ,并返回该内存的地址,在getA函数结束之后申请的内存并不会消失,因为是在堆上申请的,销毁的只不过是栈中的变量,包括变量a,可是在变量a销毁之前已经把a中的值(也就是堆上那块内存的地址)返回了。因此b获取了该地址,b也就变的有意义了。后面的逻辑就通了。
首先楼主没有搞清楚哪种内存是在堆上的,而且楼主虽然知道函数结束之后会销毁栈上的变量,这一理解只是停留在表面上,并没有深刻的理解这句话的含义!最后楼主对于指针的运用不到位,有空去看看指针方面的书。
解决方案四:
“v1不一定在堆栈上,在不在堆栈上要看它属于的那个A的实例对象在不在堆栈上。”这是对的。
解决方案五:
楼主确实态度有问题。关于你要一个权威的说法,你可以看C++ primer的18.1.1,有和2楼几乎一样的话。
解决方案六:
你没有搞清楚普通变量和指针变量在访问过程上的不同,
也没有搞清楚变量内存的存放形式。
建议你把这段代码反编译,汇编级调试一下,你就明白了。
解决方案七:
我只是想确定c++语句vector v1;v1对象不一定放在栈中,正如caozhy所说,“v1不一定在堆栈上,在不在堆栈上要看它属于的那个A的实例对象在不在堆栈上。”如果这句话是对的,那么就没有问题了,只是换个角度问这个问题,因为我实在不能确定这句话是否正确?哪位高手能告诉一下,这哪里有一个权威出处吗??
解决方案八:
是这样的,虽然你调用了函数getA来获取A对象,但是你获取的那个A对象是在堆上分配的,getA函数返回时,系统会清理getA函数栈上的数据,但因为
A对象是在堆上分配的,并不会被清理掉,所以你的函数可以获得正确结果。对于C++对象的内存分配方式,数据作用域多了解下就清楚了。
解决方案九:
有啥问题可以直接找我
解决方案十:
我晕,v1是你指针a的成员,a在堆上,v1自然也在堆上。