相关疑难解决方法(0)

std :: vector*在增加容量时是否有*移动对象?或者,分配器可以"重新分配"吗?

一个不同的问题启发了以下思想:

在增加容量时是否std::vector<T> 必须移动所有元素?

据我所知,标准行为是底层分配器请求新大小的整个块,然后移动所有旧元素,然后销毁旧元素,然后解除分配旧内存.

在给定标准分配器接口的情况下,此行为似乎是唯一可能的正确解决方案.但我想知道,修改分配器以提供一个reallocate(std::size_t)可以返回a pair<pointer, bool>并可以映射到底层的函数是否有意义realloc()?这样做的好处是,如果操作系统实际上只能扩展分配的内存,那么根本不需要进行任何移动.布尔值表示内存是否已移动.

(std::realloc()也许不是最好的选择,因为如果我们不能扩展,我们不需要复制数据.所以实际上我们更想要类似的东西extend_or_malloc_new().编辑:也许is_pod基于特征的专业化将允许我们使用实际的realloc,包括它的按位副本.只是不一般.)

这似乎错过了机会.最坏的情况下,可以始终贯彻reallocate(size_t n)return make_pair(allocate(n), true);,所以不会有任何惩罚.

是否有任何问题导致此功能对C++不合适或不合适?

也许唯一可以利用这个的容器就是std::vector,但那时又是一个相当有用的容器.


更新:澄清一个小例子.目前resize():

pointer p = alloc.allocate(new_size);

for (size_t i = 0; i != old_size; ++i)
{
  alloc.construct(p + i, T(std::move(buf[i])))
  alloc.destroy(buf[i]);
}
for (size_t i = old_size; i < new_size; ++i)
{
  alloc.construct(p + i, T());
}

alloc.deallocate(buf); …
Run Code Online (Sandbox Code Playgroud)

c++ vector realloc allocator

51
推荐指数
2
解决办法
3107
查看次数

为什么C++分配器中没有重新分配功能?

在C中,标准内存处理函数是malloc(),realloc()free().但是,C++ stdlib分配器只兼容其中两个:没有重新分配功能.当然,不可能完全相同realloc(),因为简单地复制内存不适合非聚合类型.但是,这个函数是否会出现问题:

bool reallocate (pointer ptr, size_type num_now, size_type num_requested);
Run Code Online (Sandbox Code Playgroud)

哪里

  • ptr先前为num_now对象分配了相同的分配器;
  • num_requested> = num_now;

和语义如下:

  • 如果分配器可以ptr从给定num_now对象的大小扩展给定的内存块num_requested,它会这样做(留下额外的内存未初始化)并返回true;
  • 否则它什么都不做并返回false.

当然,这不是很简单,但据我所知,分配器主要用于容器和容器的代码通常很复杂.

给定这样的函数,std::vector比如说,可以增长如下(伪代码):

if (allocator.reallocate (buffer, capacity, new_capacity))
  capacity = new_capacity;     // That's all we need to do
else
  ...   // Do the standard reallocation by using a different buffer,
        // copying data and freeing the current one …
Run Code Online (Sandbox Code Playgroud)

c++ memory-management realloc

33
推荐指数
3
解决办法
3829
查看次数

良好的C++数组类,以快速和内存有效的方式处理大型数据数组?

继上一个与堆使用限制相关的问题之后,我正在寻找一个好的标准C++类,以一种既节省内存又提高速度的方式处理大数据数据.我一直在使用单个malloc/HealAlloc分配数组,但是在使用各种调用的多个trys之后,继续犯下堆碎片.因此,除了移植到64位之外,我得出的结论是使用一种机制,允许我拥有一个跨越多个较小内存片段的大型数组.我不希望每个元素都有一个alloc,因为它的内存效率很低,所以计划是编写一个覆盖[]运算符的类,并根据索引选择一个合适的元素.是否已经有一个体面的班级来做这件事,或者我最好自己动手?

根据我的理解和一些谷歌搜索,32位Windows进程理论上应该可以解决高达2GB的问题.现在假设我已经安装了2GB,并且各种其他进程和服务占用大约400MB,你认为我的程序可以合理地期望从堆中获得多少可用内存?

我目前正在使用各种风格的Visual C++.

编辑 按照Poita的帖子,我尝试了一个std :: deque,在VS2008上使用以下测试;

#include <deque>
using namespace std;
struct V    
{
    double  data[11];
};

struct T
{
    long    data[8];    
};


void    dequeTest()
{
    deque<V> VQ;
    deque<T> TQ;

    V defV;
    T defT;

    VQ.resize(4000000,defV);
    TQ.resize(8000000,defT);
}
Run Code Online (Sandbox Code Playgroud)

上述数据的总内存为608MB,如果我使用直接malloc或HeapAlloc,则需要<1秒.deque resizes最初占用了950MB,然后慢慢开始退回.15分钟后,dequeTest()完成了,只使用了6MB的内存显示进程,这可能更多地与运行时间有关.我也尝试使用各种推送选项填充双端队列,但性能非常糟糕,我不得不提前爆发.我可以提供一个比defualt更好的分配器来获得更好的响应,但从表面来看,deque并不是这项工作的类.请注意,这也可能与deque的MS VS2008实现有关,因为在这个类中似乎有很多与性能相关的非常依赖于实现的实现.

我想,是时候写我自己的大数组了.

第二次编辑: 使用以下内容立即分配较小的数量,产生1.875GB;

#define TenMB 1024*1024*10

void    SmallerAllocs()
{

    size_t Total = 0;
    LPVOID  p[200];
    for (int i = 0; i < 200; i++)
    {
        p[i] = malloc(TenMB);
        if (p[i])
            Total += …
Run Code Online (Sandbox Code Playgroud)

c++ arrays visual-c++

8
推荐指数
2
解决办法
3306
查看次数