Подтвердить что ты не робот

Поиск размера динамически распределенного массива

Почему невозможно получить длину выделенного таким образом буфера.

AType * pArr = new AType[nVariable];

Когда один и тот же массив освобождается

delete [] pArr;

среда выполнения должна знать, сколько можно освободить. Есть ли какие-либо средства для доступа к длине перед удалением массива. Если нет, то почему такой API не предоставляется, чтобы получить длину?

4b9b3361

Ответ 1

Есть ли какие-либо средства для доступа к длине перед удалением массива?

Нет. нет способа определить это.
Стандарт не требует, чтобы реализация запоминалась и предоставляла спецификацию количества элементов, запрошенных через new.
Реализация может просто вставить конкретные битовые шаблоны в конце выделенных блоков памяти вместо того, чтобы помнить количество элементов, и может просто искать шаблон при освобождении памяти.
Короче говоря, это исключительно детализация.


С одной стороны, есть две возможности для решения этой проблемы:

  • Вы можете просто использовать std::vector, который предоставляет вам функции-члены, такие как size() или
  • Вы можете просто заниматься бухгалтерией.

new atleast выделяет достаточно памяти столько, сколько вы просили.
Вы уже знаете, сколько памяти вы запросили, чтобы вы могли легко вычислить длину. Вы можете найти размер каждого элемента, используя sizeof.

Total memory requested / Memory required for 1 item = No of Items

Ответ 2

Среда выполнения знает, сколько было выделено. Однако такие детали специфичны для компилятора, поэтому у вас нет кросс-платформенного способа обработки.

Если вам нужна такая же функциональность и вы сможете отслеживать размер, вы можете использовать std::vector следующим образом:

std::vector< AType > pArr( nVariable );

У этого есть дополнительное преимущество использования RAII.

Ответ 3

Оператору delete не нужно знать размер, чтобы освободить выделенную память, как и системный вызов free. Это связано с тем, что эта проблема остается для операционной системы, а не для среды выполнения компиляторов.

Ответ 4

Среда выполнения должна освободить ту же сумму, что и она, и она Следите за этим в некотором роде (как правило, очень косвенно). Но нет надежного способа получить от суммы, выделенной на количество элементов: выделенная сумма не может быть меньше количества элементы раз по размеру каждого элемента, но часто это будет больше. Например, соображения согласования означают, что new char[5] и new char[8] будут часто выделять один и тот же объем памяти, и есть различные стратегии распределения, которые могут привести к значительному увеличению объема памяти чтобы было выделено то, что строго необходимо.

Ответ 5

Нет, не совсем. По крайней мере, не в платформенно-независимом, определенном виде.

Большинство реализаций сохраняют размер динамически распределенного массива до фактического массива.

Ответ 6

В С++ нет переносного способа для получения размера динамически выделенного массива из необработанного указателя.

В MSVC и WIN32 вы можете получить размер выделенного блока с помощью функции _msize (void *).

см. https://msdn.microsoft.com/en-us/library/z2s077bc.aspx для более подробной информации.

Ответ 7

почему бы не добавить дополнительную информацию:

template <typename T> class AType
{
public:

    AType(size_t s) : data(0)
    {
        a_size = s;
        data = new T[s];
    }
    ~AType() {
        if (data != nullptr)
            delete [] data;
    }

    size_t getSize() const
    {
        return a_size * sizeof(T);
    }

private:
    size_t a_size;
    T* data;
};