C++ 这两个向量语句之间的区别是什么?

C++ 这两个向量语句之间的区别是什么?,c++,C++,[!!对第二个代码进行了更正!!] vector<int> a; vector<int>*p = &a; 及 我知道在第一个场景中,a在堆栈上,而在第二个场景中,b在堆上。但是,还有其他区别吗?与内存消耗等类似。p和q只是指向向量的指针,向量在堆栈上初始化 在大多数平台上,它应该只能容纳4个字节 p和q只是指向向量的指针,向量在堆栈上初始化 在大多数平台上,它应该只能容纳4个字节 Err,p和q都是指向向量的指针,都分别指向a和b的地址。它们本质上是一样的,但我

[!!对第二个代码进行了更正!!]

vector<int> a;
vector<int>*p = &a;


我知道在第一个场景中,a在堆栈上,而在第二个场景中,b在堆上。但是,还有其他区别吗?与内存消耗等类似。

p和q只是指向向量的指针,向量在堆栈上初始化


在大多数平台上,它应该只能容纳4个字节

p和q只是指向向量的指针,向量在堆栈上初始化


在大多数平台上,它应该只能容纳4个字节

Err,p和q都是指向向量的指针,都分别指向a和b的地址。它们本质上是一样的,但我可能会对第二个例子中的格式设置感到生气


这只是语法间距的一个小小的调整,在第一个向量对的第二行缺少一个分号。

呃,p和q都是指向向量的指针,都分别指向a和b的地址。它们本质上是一样的,但我可能会对第二个例子中的格式设置感到生气


这只是语法间距上的一个小小的调整,第一个向量对的第二行缺少一个分号。

q是指向堆栈上对象b的指针。指针对象只是一个地址A数字,而b是一个向量实例

q是指向堆栈上对象b的指针。指针对象只是一个地址A数字,而b是一个向量实例

是的,向量b在堆上分配,向量A在堆栈上,假设代码在方法的范围内,并且4字节指针也在堆栈上。内存消耗的其他差异将取决于内存管理器以及它如何分配块和堆所需的任何内部簿记。

是向量b在堆上分配,向量a在堆栈上,假设代码在方法的范围内,以及堆栈上的4字节指针。内存消耗的其他差异将取决于内存管理器、内存管理器如何分配块以及堆所需的任何内部簿记。

原始问题: 你在问,两者之间的区别是什么

vector<int> a;
vector<int>*p = &a 
vector<int> a;
vector<int>*p = &a 

在第一种情况下,您有一个向量,并声明一个指针,该指针被初始化为指向该向量。这种额外的间接性通常不是一个好主意

在第二种情况下,声明一个指向向量的指针,并将其初始化为指向通过new分配的零大小向量。这绝对不是个好主意。矢量为您进行内存管理,这很重要:只需对诱人的新特性说“不”

就这些

干杯,

原始问题: 你在问,两者之间的区别是什么

vector<int> a;
vector<int>*p = &a 
vector<int> a;
vector<int>*p = &a 

在第一种情况下,您有一个向量,并声明一个指针,该指针被初始化为指向该向量。这种额外的间接性通常不是一个好主意

在第二种情况下,声明一个指向向量的指针,并将其初始化为指向通过new分配的零大小向量。这绝对不是个好主意。矢量为您进行内存管理,这很重要:只需对诱人的新特性说“不”

就这些

干杯

我知道在第一个场景中,a在堆栈上,而在第二个场景中,b在堆上

这句话的两个部分都是错误的。 主要是因为术语栈/堆在描述C++对象时是无用的。
 vector<int>   a;
这是指向对象的指针。它指向什么取决于。在本例中,您将它指向一个自动对象,如上所述,该对象可能位于堆栈或堆上

最后:

vector<int>*   q = new vector<int>();
这是指向具有动态存储持续时间的对象的指针。这意味着它是用new创建的,并且必须手动销毁,这也是为什么你从不创建原始指针,它们总是用智能指针包装的。请阅读一本书。如果这个对象在堆栈或堆上,取决于语言的很多东西,你可以用简单的天真方式重写默认行为,你可以把它看作堆上的,但是最好不要忘记堆和栈的概念,因为它们不适用于C++。 最好将物体分为四类:

静态存储持续时间对象 全局变量和其他一些东西 你可以想象这些,直到你知道更多的是在主站被摧毁之前,在主站被摧毁之后 线程存储持续时间对象 与线程关联的全局变量。 您可以将其视为在线程被销毁后创建的 自动存储持续时间对象 几乎所有其他物体 这些是在第一次遇到时创建的。 当它们超出范围时被摧毁。 范围取决于上下文。 动态存储持续时间对象 使用new分配的对象和使用delete取消分配的对象。 应包含在智能指针或容器中的对象 我知道在第一个场景中,a在堆栈上,而在第二个场景中,b在堆上

这句话的两个部分都是错误的。 主要是因为使用了术语stack/heap 更少描述C++对象。

 vector<int>   a;
这是指向对象的指针。它指向什么取决于。在本例中,您将它指向一个自动对象,如上所述,该对象可能位于堆栈或堆上

最后:

vector<int>*   q = new vector<int>();
这是指向具有动态存储持续时间的对象的指针。这意味着它是用new创建的,并且必须手动销毁,这也是为什么你从不创建原始指针,它们总是用智能指针包装的。请阅读一本书。如果这个对象在堆栈或堆上,取决于语言的很多东西,你可以用简单的天真方式重写默认行为,你可以把它看作堆上的,但是最好不要忘记堆和栈的概念,因为它们不适用于C++。 最好将物体分为四类:

静态存储持续时间对象 全局变量和其他一些东西 你可以想象这些,直到你知道更多的是在主站被摧毁之前,在主站被摧毁之后 线程存储持续时间对象 与线程关联的全局变量。 您可以将其视为在线程被销毁后创建的 自动存储持续时间对象 几乎所有其他物体 这些是在第一次遇到时创建的。 当它们超出范围时被摧毁。 范围取决于上下文。 动态存储持续时间对象 使用new分配的对象和使用delete取消分配的对象。 应包含在智能指针或容器中的对象
这两个向量都将为堆上的元素分配内存。 主要区别在于向量对象的生命周期。在第一种情况下,它位于堆栈上,并将在其作用域结束时销毁


在第二种情况下,向量将保留在内存中,直到调用delete q。

这两个向量都将为堆上的元素分配内存。 主要区别在于向量对象的生命周期。在第一种情况下,它位于堆栈上,并将在其作用域结束时销毁


在第二种情况下,向量将保留在内存中,直到调用delete q。

就像指出自动分配不需要堆栈分配一样。如果使用全局向量,它不一定在堆栈上,但可能位于自动分配变量的某些特殊内存中。另外,如果向量是类成员,它的位置取决于类实例所在的位置?那是编译器依赖的吗?@Ken:全局向量不是自动向量,那么它在堆栈上的位置或者其他方面与自动向量的位置有什么关系?诚然,该标准没有为自动变量指定堆栈,但它指定了足够的行为,无论自动变量存储在哪里,都开始看起来非常像堆栈。但实现者原则上可以从mark-sweep垃圾收集器或其他东西分配堆栈帧,如果他们真的愿意的话。仅从代码片段我们无法判断a是否是自动的。我相信向量的默认容量取决于您使用的STL实现。唯一的保证是向量的大小为零。@Steve:是的,这是真的。C++中有一个短语,它指的是表单类型A的非动态分配吗?我想指出的是,自动分配并不需要堆栈分配。如果使用全局向量,它不一定在堆栈上,但可能位于自动分配变量的某些特殊内存中。另外,如果向量是类成员,它的位置取决于类实例所在的位置?那是编译器依赖的吗?@Ken:全局向量不是自动向量,那么它在堆栈上的位置或者其他方面与自动向量的位置有什么关系?诚然,该标准没有为自动变量指定堆栈,但它指定了足够的行为,无论自动变量存储在哪里,都开始看起来非常像堆栈。但实现者原则上可以从mark-sweep垃圾收集器或其他东西分配堆栈帧,如果他们真的愿意的话。仅从代码片段我们无法判断a是否是自动的。我相信向量的默认容量取决于您使用的STL实现。唯一的保证是向量的大小为零。@Steve:是的,这是真的。C++中有一个短语,它指的是窗体类型A的任何非动态分配;?@匿名否决投票人:请解释你否决投票的原因,以便其他人可以从你的见解中受益。我只是想知道-我猜他们是根据你最初的答案否决了投票,而你的答案在编辑完OP后就不再有意义了?我已经为奇偶校验+1:-我没有投反对票,因为我同意代码行从来都不是一个好主意,但如果有一个指向动态分配向量的指针(如果不同的话)也不一定是一个坏主意

所有的代码位都与同一个向量交互。从new初始化它是个坏主意,因为new需要一些rai来管理它。获取原始指针的正确位置是智能指针的操作符->-@史蒂夫·杰索普(Steve Jessop)从智能指针的操作符->处得到一个原始指针对我来说是一种困惑。通常,如果您需要指向某个对象的原始指针,那么无论如何都不应该由智能指针管理。但是,很少有事情应该由智能指针来管理。如果你需要RAII来管理一些东西,那么它可能不应该首先分配到堆中。@James:对不起,那是开玩笑的。我的意思是,当您将->与智能指针一起使用时,实现将为自己找到原始指针。至于大多数RAII管理的对象是否是堆分配的:这取决于程序和您对RAII的确切定义。我认为所有动态分配的对象都应该由RAII管理,并且应该尽可能少,所以可能的问题是,您还有多少其他由RAII管理的东西:锁或其他。@anonymous downvoter:请解释您进行downvoting的原因,所以其他人可以从你的见解中受益,呵呵。我只是想知道——我猜他们是根据你最初的答案投了反对票,而你的答案在编辑完OP后就不再有意义了?我已经为奇偶校验+1:-我没有投反对票,因为我同意代码行从来都不是一个好主意,但如果不同的代码位都与同一个向量交互,那么有一个指向动态分配向量的指针也不一定是一个坏主意。从new初始化它是个坏主意,因为new需要一些rai来管理它。获取原始指针的正确位置是智能指针的操作符->-@史蒂夫·杰索普(Steve Jessop)从智能指针的操作符->处得到一个原始指针对我来说是一种困惑。通常,如果您需要指向某个对象的原始指针,那么无论如何都不应该由智能指针管理。但是,很少有事情应该由智能指针来管理。如果你需要RAII来管理一些东西,那么它可能不应该首先分配到堆中。@James:对不起,那是开玩笑的。我的意思是,当您将->与智能指针一起使用时,实现将为自己找到原始指针。至于大多数RAII管理的对象是否是堆分配的:这取决于程序和您对RAII的确切定义。我认为所有动态分配的对象都应该是RAII管理的,并且应该尽可能少,所以可能的问题是你还有多少其他RAII管理的东西:锁或其他什么。智能指针并不是他们所说的全部。它们可以像原始指针一样被滥用。这是一个芳香的存储持续时间he-he:-我认为你有相反的东西-以一种简单天真的方式,你可以想到堆栈上的自动操作和堆上的动态分配对象,但你写的是相反的。看起来如果你在一个函数中,它被放在堆上是错误的。你能把你的答案说得更全面些吗?我认为所有自动对象都是在堆栈上分配的。@Bo Persson:可能是故意的!因为它们不是一种代码气味,它们是一种坏气味的反面,因此是一种好的代码气味或芳香代码:-智能指针并不是人们所说的全部。它们可以像原始指针一样被滥用。这是一个芳香的存储持续时间he-he:-我认为你有相反的东西-以一种简单天真的方式,你可以想到堆栈上的自动操作和堆上的动态分配对象,但你写的是相反的。看起来如果你在一个函数中,它被放在堆上是错误的。你能把你的答案说得更全面些吗?我认为所有自动对象都是在堆栈上分配的。@Bo Persson:可能是故意的!因为它们不是代码气味,所以它们与坏气味相反,因此好代码气味或芳香代码:-b不需要在堆栈上。它可以很容易地放在堆上。b不需要放在堆栈上。它也可以很容易地放在堆上。这个答案的第一句话是不正确的,正如Martin的优秀答案所解释的。还应该注意到,两个向量都将包含的int保留在堆中,不同之处在于向量将其指针指向“int”和其他元信息。对于发布的32位MSVC2010,其_SECURE_SCL=0,向量为12字节。如Martin的优秀答案所述,此答案的第一句不正确。还应注意,这两个向量都会将包含的整数保留在堆中,不同之处在于向量保持指向“int”和其他元信息的指针。对于版本为_SECURE_SCL=0的32位MSVC2010,向量为12字节。