假设我们有4个课程如下:
class A
{
public:
A(void) : m_B()
{
}
private:
B m_B;
}
class B
{
public:
B(void)
{
m_i = 1;
}
private:
int m_i;
}
class C
{
public:
C(void)
{
m_D = new D();
}
~C(void)
{
delete m_D;
}
private:
D *m_D;
}
class D
{
public:
D(void)
{
m_i = 1;
}
private:
int m_i;
}
Run Code Online (Sandbox Code Playgroud)
可以说有4种情况:
情况1:在堆栈上外部分配,B在堆栈内部分配
A myA1;
Run Code Online (Sandbox Code Playgroud)
情况2:在堆上外部分配,B内部分配在堆栈上
A *myA2 = new A();
Run Code Online (Sandbox Code Playgroud)
情况3:C在堆栈外部分配,D在堆内部分配
C myC1;
Run Code Online (Sandbox Code Playgroud)
情况4:C在堆上外部分配,D在堆内部分配
C *myC2 = new …Run Code Online (Sandbox Code Playgroud) 根据引用,simple std::vector<T> vec;创建了一个emtpy容器(默认构造函数).这是否保证没有动态内存分配?或者一个实现可能选择保留一些内存?
我知道,对于这个空构造函数,T自C++ 11以来没有类型的构造.但是,我想知道,如果还保证堆上没有分配任何内容.即上面的行只是nullptr堆栈/成员上的几个.
我用vc140测试了它,它确实没有动态分配.
我是C++的新手,我在项目中使用了矢量类.我发现它非常有用,因为我可以有一个数组,只要有必要就会自动重新分配(例如,如果我想推送一个项目并且向量已达到它的最大容量,它会重新分配自己,为操作系统提供更多的内存空间),所以对向量元素的访问非常快(它不像列表,要达到"第n"元素,我必须通过"n"个第一个元素).
我发现这个问题非常有用,因为当我想将我的向量存储在堆/堆栈上时,他们的答案完全解释了"内存分配器"是如何工作的:
[1] vector<Type> vect;
[2] vector<Type> *vect = new vector<Type>;
[3] vector<Type*> vect;
Run Code Online (Sandbox Code Playgroud)
然而,怀疑是困扰我一段时间,我找不到它的答案:每当我构建一个向量并开始推入大量项目时,它将达到向量将满的时刻,因此继续增长它需要重新分配,将自身复制到一个新位置,然后继续push_back项(显然,这个重新分配它隐藏在类的实现上,所以它对我来说是完全透明的)
好吧,如果我在堆上创建了向量[2],我没有想象可能发生的事情:类向量调用malloc,获取新空间然后将自身复制到新内存中,最后删除调用free的旧内存.
然而,当我在堆栈上构造一个向量时,面纱会隐藏正在发生的事情[1]:当向量必须重新分配时会发生什么?AFAIK,无论何时在C/C++上输入一个新函数,计算机都会查看变量声明,然后展开堆栈以获得放置这些变量所需的空间,但是当你在堆栈中分配更多空间时功能已在运行.类向量如何解决这个问题?
我首先假设一般来说,在堆栈中分配小对象,在动态内存中分配大对象是个好主意.另一个假设是,在尝试学习内存,STL容器和智能指针时,我可能会感到困惑.
考虑下面的例子,我有一个必须通过智能指针在免费商店中分配的对象,例如,我可以依赖客户从工厂获取所述对象.此对象包含一些使用STL容器专门分配的数据,该容器恰好是std :: vector.在一种情况下,这个数据向量本身是使用一些智能指针动态分配的,而在另一种情况下我只是不使用智能指针.
设计A和设计B之间是否存在实际差异,如下所述?
情况A:
class SomeClass{
public:
SomeClass(){ /* initialize some potentially big STL container */ }
private:
std::vector<double> dataVector_;
};
Run Code Online (Sandbox Code Playgroud)
情况B:
class SomeOtherClass{
public:
SomeOtherClass() { /* initialize some potentially big STL container,
but is it allocated in any different way? */ }
private:
std::unique_ptr<std::vector<double>> pDataVector_;
};
Run Code Online (Sandbox Code Playgroud)
一些工厂功能.
std::unique_ptr<SomeClass> someClassFactory(){
return std::make_unique<SomeClass>();
}
std::unique_ptr<SomeOtherClass> someOtherClassFactory(){
return std::make_unique<SomeOtherClass>();
}
Run Code Online (Sandbox Code Playgroud)
使用案例:
int main(){
//in my case I can reliably assume that objects themselves
//are going to always be allocated …Run Code Online (Sandbox Code Playgroud) 好吧,经过一整年的编程并且只了解数组之后,我意识到了向量的存在(由 StackOverflow 的一些成员在我之前的一篇文章中)。我自己做了大量的研究和研究,并重写了我用数组、链表和向量编写的整个应用程序。此时,我不确定是否还会使用数组,因为向量似乎更加灵活和高效。由于它们具有自动增大和缩小大小的能力,我不知道我是否会同样多地使用数组。在这一点上,我个人认为数组的唯一优点是更容易编写和理解。数组的学习曲线没什么,向量的学习曲线很小。不管怎样,我确信在某些情况下使用数组和在其他情况下使用向量可能有充分的理由,我只是好奇社区的想法。我完全是一个新手,所以我认为我对两者的严格用法都不够了解。
如果有人稍微好奇的话,这就是我正在练习使用向量的应用程序。它真的很粗糙,需要大量的工作: https ://github.com/JosephTLyons/Joseph-Lyons-Contact-Book-Application
如果我使用这条线
std:vector<MyObject>* vec = new std::vector<MyObject>(100);
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)MyObject obj1; vec->push_back(obj1);
那么,如果它进入堆栈,那么添加到向量中的 MyObject 将在方法结束后消失?向量里面会有什么?垃圾?
我应该用这个代替吗?:
std:vector<MyObject*>* vec = new std::vector<MyObject*>(100);
如果是这样,那么每个 MyObject 内的对象和基元又如何呢?它们也应该动态创建吗?
谢谢
我刚刚在SO上阅读了这篇文章,讨论了存储器中STL向量的存储位置.根据接受的答案,
vector<int> temp;
Run Code Online (Sandbox Code Playgroud)
堆栈上向量的头信息,但堆上的内容.
在这种情况下,以下代码是否会出错?
vector<int> some_function() {
vector<int> some_vector;
some_vector.push_back(10);
some_vector.push_back(20);
return some_vector;
}
Run Code Online (Sandbox Code Playgroud)
我应该用vector<int> *some_vector = new vector<int>吗?以上代码会导致一些内存分配问题的代码吗?如果我使用自定义类的实例而不是int?
知道这些容器已经管理了内存,在STL容器(向量,地图等)中使用智能指针有什么好处?
例:
std::vector<std::unique_ptr<int>>
Run Code Online (Sandbox Code Playgroud)
代替
std::vector<int*>
Run Code Online (Sandbox Code Playgroud) 你不能有:
int array[1000000];
Run Code Online (Sandbox Code Playgroud)
但是您可以制作vector并存储这 1000000 个元素。
这是因为数组存储在堆栈中并且没有足够的空间来增长吗?
当你使用向量代替时会发生什么?
它如何防止存储过多元素的问题?
对于以下结构体,由于 v 是动态分配的对象,那么内存对齐如何工作?struct S即使 v 的大小变大,其大小也是恒定的吗?那么 v 本质上是作为一个指针(或者某种指针的包装器)工作的吗?
struct S {
ANY_TYPE a;
std::vector<ANY_TYPE> v;
} s;
Run Code Online (Sandbox Code Playgroud)
如果上述所有问题的答案都是肯定的,那么随着 v 大小的变化,其成员的内存存储在哪里?这些内存是在堆上还是在堆栈上?
编辑:我看到这个问题的反对票,并意识到我应该对 std::vector 本身进行更多研究。我读了这篇文章,一切都清楚了。感谢您的回答!