Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/rest/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 新任务中以前的数据会发生什么变化?_C++_C++11_Memory_Vector_Types - Fatal编程技术网

C++ 新任务中以前的数据会发生什么变化?

C++ 新任务中以前的数据会发生什么变化?,c++,c++11,memory,vector,types,C++,C++11,Memory,Vector,Types,考虑以下代码- { int n = 3; n = 5; std::vector<int> v = { 1, 2, 3 .... 3242}; v = std::vector<int>{10000, 10001, 10002... 50000}; } { int n=3; n=5; 向量v={1,2,3..3242}; v=std::向量{10000,10001,10002…50000}; } 对于像int这样的基本数据类型,它可以简单

考虑以下代码-

{
    int n = 3;
    n = 5;

    std::vector<int> v = { 1, 2, 3 .... 3242};
    v = std::vector<int>{10000, 10001, 10002... 50000};
}
{
int n=3;
n=5;
向量v={1,2,3..3242};
v=std::向量{10000,10001,10002…50000};
}
对于像
int
这样的基本数据类型,它可以简单地用新值覆盖以前的内存位置,然后不使用它。但是,像
std::vector
这样的类型会发生什么情况,其中先前值的长度可能与新赋值的长度不同

换句话说,当v被重新分配到新的
{10000,10001,10002…50000}
值时,零件
{1,2,3…3000}
会发生什么情况。它是否只是扔掉以前的值并将内部指针重新分配到新位置?或者,它是否尽可能用新数据覆盖以前的位置,并在分配较大时重新分配新内存,或者在分配较短时清除现有内存,从而保留初始向量的
容量()

因为我在某个地方看到了这种类型的代码,所以在任何地方这比清除内容(
v=vector{}
vs
.clear()
)更可取吗

但是,像std::vector这样的类型会发生什么情况,其中先前值的大小可能与新赋值不同

我想你是说新数据数组的长度可能不同

std::vector
将其内部存储的问题与该存储的使用量分开。如果新数据具有更少、相同或更多的元素,则对象通常会重复使用相同的存储。这比简单地被覆盖要复杂得多,因为旧对象需要调用它们的析构函数(如果它们不是吊舱的话),但本质上是这样的。它们被(安全地)覆盖

如果您查看
std::vector
的源代码,您将看到许多非常复杂的代码,涵盖了您提到的所有情况,还有一些您没有看到的

编写一个异常安全的、最优有效的向量并非易事

除非您对实现感兴趣(因为您想改进、维护它或只是好奇),否则
std::vector
的行为文档足以说明您对它的期望

请特别注意哪些操作导致迭代器无效。这是一个有用的提示,表明内部对象正在存储中移动,或者可能会分配新的存储

链接:

但是,像std::vector这样的类型会发生什么情况,其中先前值的大小可能与新赋值不同

我想你是说新数据数组的长度可能不同

std::vector
将其内部存储的问题与该存储的使用量分开。如果新数据具有更少、相同或更多的元素,则对象通常会重复使用相同的存储。这比简单地被覆盖要复杂得多,因为旧对象需要调用它们的析构函数(如果它们不是吊舱的话),但本质上是这样的。它们被(安全地)覆盖

如果您查看
std::vector
的源代码,您将看到许多非常复杂的代码,涵盖了您提到的所有情况,还有一些您没有看到的

编写一个异常安全的、最优有效的向量并非易事

除非您对实现感兴趣(因为您想改进、维护它或只是好奇),否则
std::vector
的行为文档足以说明您对它的期望

请特别注意哪些操作导致迭代器无效。这是一个有用的提示,表明内部对象正在存储中移动,或者可能会分配新的存储


link:

这两种方法都可以,这取决于
vector
的实现者,您正在使用移动分配。该标准本质上要求丢弃现有数据,销毁其所有元素,并从右侧移动新数据。这是因为操作必须与受体载体的当前大小成线性关系,并且与供体的大小无关。此外,所有指向施主元素的引用、指针和迭代器必须保持有效(但现在引用目标中的元素)——这也排除了类似“从右向左复制元素”的情况。许多事情发生在这第四行,但您可能对调用感兴趣。您可以使用调试器单步执行此函数,以查看
std::vector
的实现中到底发生了什么。在debug build中执行此操作,因为发布版本可能会优化所有内容。它可以执行这两种操作中的任何一种,这取决于
vector
的实现者,您正在使用移动分配。该标准本质上要求丢弃现有数据,销毁其所有元素,并从右侧移动新数据。这是因为操作必须与受体载体的当前大小成线性关系,并且与供体的大小无关。此外,所有指向施主元素的引用、指针和迭代器必须保持有效(但现在引用目标中的元素)——这也排除了类似“从右向左复制元素”的情况。许多事情发生在这第四行,但您可能对调用感兴趣。您可以使用调试器单步执行此函数,以查看
std::vector
的实现中到底发生了什么。在调试版本中这样做,因为发布版本可能会优化所有内容。虽然您的答案通常是正确的(“不要担心”),但OP给出的具体示例是移动任务。移动分配保证了复杂性(如果分配器比较相等,复杂性与rhs的大小无关),这意味着移动分配必须“丢弃”