Я работаю со списком массива в C++, каждый в объекте и хотел разбить некоторые из них. Они распределяются динамически.
Я хотел сделать раскол в постоянное время, поскольку это теоретически возможно: из
[ pointer, size1 ]
в
[ pointer, size2 ]; [ other array ]; [ pointer + size2, size1-size2 ]
(+ other data each time)
Я попытался использовать malloc
и просто создать новый указатель, увеличенный с размером. Как и следовало ожидать, я получил ошибку из-за автоматического освобождения памяти.
Я попробовал realloc
начиная со второго адреса, но, как и в "какой разница между malloc
и calloc
" на этом сайте, уже сказал мне, что это невозможно.
Есть ли способ избежать повторной обработки второй части и правильно определить указатель? Имея линейную стоимость, где я знаю, у меня может быть постоянное время, это расстраивает.
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;
}
ничего сложного
Я не думаю, что вы можете иметь только часть динамического массива, освобожденную путем отслеживания указателей и длины. Однако вы можете подделать это, создав новый класс для управления стартовым массивом, выделив его, как вы хотите, и сохраните его с помощью std :: shared_ptr.
Вы просто возвращаете класс, содержащий shared_ptr в память, простой указатель на первый элемент и размер массива. Когда текущий класс 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
В принципе, библиотека malloc не может справиться с mallocing куском памяти, а затем освобождение его фрагментов.
Вы можете делать то, что хотите, но вы должны только освобождать память сразу в конце, используя исходный указатель, который вам дал malloc.
например
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++, которые вы можете использовать.
Вопрос относительно неясен
Но согласно вашей теме
разбиение динамически распределенного массива без линейной копии времени
я бы предложил вам использовать связанный список вместо массива, вам не нужно ничего копировать (и, следовательно, не нужно ничего освобождать, если вы не захотите удалить один из элементов), манипулирование указателями будет достаточно для разделения связанного списка
Возможно, вы можете использовать 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
Я думаю, что malloc
и создать новую идею указателя хорошо. Но вам нужно освободить память вручную, я думаю.