首页 新闻 赞助 找找看

c++语句vector<string> v1;v1对象一定放在栈中吗?

0
[已关闭问题] 关闭于 2015-03-06 00:39

如果有这么一句程序:vector<string> v1;

v1是分配在栈上吗?不要小看这个问题,书里的基础概念我已经读了几遍,但是这个迷惑仍然不能解决,要不我就不用花时间上网来问了,期望能有高手指教,

按一般的理解,大概是这样:

C++对象存放在堆上还是栈上由你的代码控制,用new申请的对象放到堆上(new是没有重载的),否则放在栈上,比如

class A {};

A a; //A的对象在栈中分配内存
A * a = new A(); //A的对象在堆上分配内存

上面应该是没有疑问的,可是看下面代码:

#include <string>
#include <vector>
using namespace std;

class A {
public:
    A(void) :v1(10) {v1[0]="abc";}
    vector<string> 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”,为什么呢?

若解决我的迷惑给72分,我总共才72分,没有耐心或细心读问题的就不要回答了,暂时不需要粗心或太抽象的指导性的意见,谢谢!

Patrickz10的主页 Patrickz10 | 初学一级 | 园豆:7
提问于:2015-03-05 19:13
< >
分享
所有回答(2)
0

v1不一定在堆栈上,在不在堆栈上要看它属于的那个A的实例对象在不在堆栈上。

Patrickz10 | 园豆:7 (初学一级) | 2015-03-06 00:39
3

分配内存只发生在程序的执行过程中,如

int main()
{
    vector<string> v1;
}

int main()
{
    vector<string>* v1 = new vector<string>();
}

前者v1在栈中分配内存,后者在堆中分配。 也就是说 “非new的对象在栈中分配,new的对象在堆中分配” 这句话是没有问题的。

而你的这个

class A {
public:
    A(void) :v1(10) { v1[0] = "abc"; }
    vector<string> v1;
};

只是一个类的定义,还没有实例化,是不涉及到任何内存分配的,根本不适用于内存分配原则。就算实例化后,v1变量只是a对象的一个成员变量, 它在在堆上还是在栈上是由a对象的分配方式决定的,而不是由其声明方式决定的。 更进一步,分析一下成员变量的内存分布也能发现,v1本身就是和其父对象是同一地址。

    A *b = getA();
    long offset = (long)(&(b->v1)) - (long)b;   //结果是0

也就是说,当A类实例化为a对象的时候,a对象在栈上v1就在栈上,a对象在堆上v1就在堆上。在你的例子里是分配在堆上的,因此是不会随着函数结束被回收的。

天方 | 园豆:5407 (大侠五级) | 2015-03-06 00:46

你的分析太清晰太贴切了,句句都说中我的迷惑,很感谢你!可惜我先结贴了,因为我从别的地方得知我问题的题目那个命题是否定的,不过你的回答加深了我的理解,得高手不啬指点,今晚收获颇丰,谢谢!

支持(0) 反对(0) Patrickz10 | 园豆:7 (初学一级) | 2015-03-06 01:18
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册