-5

但是如果你想防止一些潜在丑陋的重物的5000个副本(或更多)。只是为了性能并忽略可读代码,您可以这样做

#include <iostream>
#include <vector>

int main(int argc, char* argv[])
{
    std::vector<int> v;
    int* a = (int*) malloc(10*sizeof(int));
    //int a[10];
    for( int i = 0; i<10;++i )
    {
        *(a + i) = i;
    }

    delete v._Myfirst; // ? not sure
    v._Myfirst = a;

    for( int i = 0; i<10;++i )
    {
        std::cout << v[i] << std::endl;
    }

    system("PAUSE");

    return 0;
}

只需替换 _Myfirst 底层“数组”。但要非常小心,这将被向量删除。

  1. 在某些情况下,我的第一次删除/释放是否失败?
  2. 这取决于分配器吗?
  3. 有交换吗?有全新的向量交换,但是从数组中呢?

我必须与无法修改的代码(政治原因)进行交互,它为我提供了对象数组,并且必须使它们成为对象的向量。

指针似乎是正确的解决方案,但它有很多内存跳转,无论如何我都必须执行循环。我只是想知道是否有某种方法可以避免复制并告诉向量,“现在这是你的底层数组”。

我同意以上内容非常难看,这就是为什么我实际上保留并推送我的真实代码。我只是想知道是否有办法避免循环。

请不要用循环和推回来回答,因为显然这就是我的“真实”代码已经在做的事情。如果没有执行此交换的功能,我们可以实现一个安全的吗?

4

3 回答 3

6

问题 1:在某些情况下,我的第一次删除/释放是否失败?

是的。您不知道内存_Myfirst是如何分配的(除了它使用分配器)。该标准未指定默认分配器应使用 malloc 分配内存,因此您不知道是否delete会起作用。

此外,您正在混合分配方案。

您正在分配malloc(). 但期望std::vector<>分配与new(因为你正在调用删除)。

此外,即使分配器确实使用了 new,它也会使用 new 的数组版本,因此您需要使用 delete 的数组版本来回收内存。

问题2:这是否取决于分配器?

是的。

问题3:有交换吗?有全新的向量交换,但来自数组?

不。

以防止昂贵的副本。使用emplace_back().

std::vector<int> v;
v.reserve(10);            // reserve space for 10 objects (min).

for( int i = 0; i<10;++i )
{
    v.emplace_back(i);   // construct in place in the array (no copy).
}
于 2013-10-23T23:05:54.357 回答
0

如果您不喜欢向量的行为方式,请不要使用向量。您的代码取决于您不得依赖的实现细节。

是的,就像你说的那样丑。使用正确的容器让它变得漂亮。

您使用哪个容器取决于您需要对容器进行哪些操作。它可能像 C 样式数组一样简单,可以满足您的需求。如果您希望该向量管理 HeavyObjects 的生命周期,它可能是一个指针向量或共享指针。


为了满足增加收藏规模的需要(见下面的评论):

std::vector 保证底层存储是连续的,因此如果增加大小,它将分配一个新的更大的缓冲区并将旧的缓冲区复制到新的缓冲区中(如果存在对象,则使用对象的复制构造函数。)然后交换新缓冲区到位——使用自己的分配器释放旧缓冲区。

这将浪费您的内存,除非您强制进入向量的缓冲区以与向量分配器一致的方式分配。

因此,如果您的原始数组足够大,您只需要一个“maxUsed”size_t 来告诉您集合有多大以及在哪里放置新条目。如果它不够大,那么你的技术要么会严重失败,要么会产生你试图避免的复制成本。

于 2013-10-23T22:52:41.623 回答
0
std::vector<SomeUglyHeavyObject*> vect(5000, NULL);
for (int i=0; i<5000; i++)
{
    vect[i] = &arr[i];
}

在那里,避免了复制,也不会破坏std::vector内部结构。

于 2013-10-23T22:58:48.983 回答