拆分动态分配的数组而不进行线性时间复制

时间:2013-11-22 14:42:26

标签: c++ arrays malloc

我正在使用C ++中的数组列表,每个数组都在一个对象中,并希望将它们中的一些分开。 这些是动态分配的。

我想在恒定时间内进行拆分,因为理论上可行:  从

[ pointer, size1 ] 

[ pointer, size2 ]; [ other array ]; [ pointer + size2, size1-size2 ]
(+ other data each time)

我尝试使用malloc并简单地创建一个以大小递增的新指针。 正如可以预料的那样,由于自动释放内存,我收到了错误。

我在第二个地址开始尝试realloc,但是在“此网站上malloccalloc之间的区别”已经告诉我这是不可能的。< / p>

有没有办法避免重新复制第二部分并正确定义指针? 我知道我可以有一个恒定时间的线性成本是令人沮丧的。

    class TableA
    {
     public:
      (constructor)
      void divide(int size); // the one i am trying to implement
      (other, geteur, seteur)
     private
      Evenement* _el;
      vector<bool>** _old;//said arrays
      int _size;
    }

没有什么真正复杂的

5 个答案:

答案 0 :(得分:1)

基本上,malloc库无法处理mallocing一块内存然后释放它的切片。

你可以做你想做的事,但你必须只使用malloc递给你的原始指针在最后一次释放所有内存。

e.g。

int* p = malloc(9 * sizeof(int));
int* q = p + 3;
int* r = p + 6;
// Now we have three pointers to three arrays of three integers.

// Do stuff with p, q, r

free(p); // p is the only pointer it is valid to free.

顺便说一下,如果这真的是关于C ++的话,可能会有标准的C ++数据结构。

答案 1 :(得分:0)

我认为malloc并创建新指针的想法很好。但是你需要手动释放内存。

答案 2 :(得分:0)

也许你可以使用std::copy

int* p = (int*)malloc(sizeof(int) * 5);
for (int i = 0; i < 5; i++)
    p[i] = i;
for (int i = 0; i < 5; i++)
    std::cout << p[i];

// tmp will hold 3 values
// p2 will hold 2 values
// so we want to copy first 3 into tmp
// and last 2 into p2
int tmp[3];
std::copy(p, p+3, tmp);
for (int i = 0; i < 3; i++)
    std::cout << tmp[i];
int p2[2];
std::copy(p+3, p+5, p2);
for (int i = 0; i < 2; i++)
    std::cout << p2[i];
// get rid of original when done
free(p);

输出:

0123401234

答案 3 :(得分:0)

问题相对不清楚

但根据你的主题

拆分动态分配的数组而不使用线性时间复制

我建议您使用链接列表而不是数组,您不需要复制任何内容(因此无需释放任何内容,除非您想要删除其中一项),操作指针足以分割链表

答案 4 :(得分:0)

我认为你不能通过跟踪指针和长度来释放动态数组的一部分。但是,您可以通过创建一个新类来管理起始数组,根据需要分配它并让它由std :: shared_ptr管理来伪造它。

您只需将包含shared_ptr的Class返回到内存,指向第一个元素的普通指针和数组大小。当前的Array类超出范围时,shared_ptr会递减,当不再使用内存片时,内存将被释放。

你需要小心这一点,因为可能有多个对象引用相同的内存,但是有方法(例如在用bool分割后标记原始无效)。

[编辑]下面是这个想法的一个非常基本的实现。 split()运算符可以非常轻松地在2 slice()次运算中实现。我不确定你要如何根据上面的例子来实现这一点,因为我不确定你是如何管理vector<bool> **的,但如果你想要分割你的vector<bool>,你就可以了可以实例化ShareVector<bool>,或者如果你有一个vector<bool>数组,那么你可以改为SharedVector<vector<bool>>

#ifndef __SharedVector__
#define __SharedVector__

#include <memory>
#include <assert.h>

template <typename T>
class SharedVector {

    std::shared_ptr<T> _data;
    T *_begin;
    size_t _size;
    // perhaps add size_t capacity if need for limited resizing arises.

public:
    SharedVector<T>(size_t const size)
    : _data(std::shared_ptr<T>(new T[size], []( T *p ) { delete[] p; })), _begin(_data.get()), _size(size)
    {}

    // standard copy and move constructors work fine

    // pass shared_ptr by reference to avoid unnecessary refcount changes
    SharedVector<T>(std::shared_ptr<T> &data, T *begin, size_t size)
    : _data(data), _begin(begin), _size(size)
    {}

    T& operator[] (const size_t nIndex) {
        assert(nIndex < _size);

        return _begin[nIndex];
    }  

    T const & operator[] (const size_t nIndex) const {
        assert(nIndex < _size);

        return _begin.get()[nIndex];
    }

    size_t size(){
        return _size;
    }

    SharedVector<T> slice(size_t const begin, size_t const end) {
        assert(begin + end < _size);

        return SharedVector<T>(_data, _begin + begin, end - begin);
    }

    T *begin() {
        return _begin;
    }

    T *end() {
        return _begin + _size;
    }
};

#endif