Перепишите этот Malloc, используя New для 2D Array

0

После некоторых проб и ошибок я нашел способ malloc 2D-массив, чтобы он был непрерывным в памяти, что эквивалентно нединамическому случаю.

int numRows =2;
int numCols = 4;
int (*p)[numCols];
p    = (int (*)[numCols]) malloc(sizeof(int)*numRows*numCols);

Таким образом, p теперь в основном такой же, как если бы я сделал int p [2] [4] - за исключением его в куче вместо стека.

2 Вопросы:

  1. Мне просто нужно позвонить бесплатно (p), чтобы освободить память? Нет циклов?
  2. Как мне преобразовать это в использование new, а не malloc?

Я пытался

p = new (int (*)[4])[2];

Но это дало ошибку:

error: cannot convert int (**)[4] to int (*)[4] in assignment
  • 2
    В C ++, не используйте malloc и даже не new 2D - массив, использовать vector<vector<int>>
  • 0
    «Мне просто нужно позвонить free (p), чтобы освободить память? Без циклов?» - Да, так как есть одно распределение. Но не приводите возвращаемое значение malloc() . В самом деле. Тогда не используйте new тоже. Сделайте vector<int> v(numRows * numCols) , инкапсулируйте его в класс, operator[] перегрузки operator[] который возвращает прокси-объект, имеющий указатель (или что-то еще) на соответствующую строку внутри вектора, перегрузите его operator[] как ну и тд
Показать ещё 2 комментария
Теги:
multidimensional-array
malloc
new-operator

3 ответа

1

Здесь шаблон класса, который использует один std::vector для хранения смежного буфера и объектов с прокси-серверами с размерами для доступа к элементам массива измерения по размеру:

template<typename T>
class TwoDArray {
private:
    std::size_t n_rows;
    std::size_t n_cols;
    std::vector<T> buf;

public:
    class OneDArrayProxy {
    private:
        T *rowptr;
        std::size_t colsize;

    public:
        OneDArrayProxy(const T *rp, std::size_t cs) : rowptr(const_cast<T *>(rp)), colsize(cs) {}
        T const &operator[](std::size_t index) const {
            return rowptr[index];
        }

        T &operator[](std::size_t index) {
            return rowptr[index];
        }

        std::size_t size() const { return colsize; }
    };

    TwoDArray(std::size_t rows, std::size_t cols) : n_rows(rows), n_cols(cols), buf(rows * cols) {}
    TwoDArray() : TwoDArray(0, 0) {}

    OneDArrayProxy operator[](std::size_t index) const {
        return OneDArrayProxy(&buf[index * n_cols], n_cols);
    }

    std::size_t rows() const { return n_rows; }
    std::size_t columns() const { return n_cols; }
};

Пример использования:

int main()
{
    TwoDArray<int> arr(9, 5);
    for (std::size_t i = 0; i < arr.rows(); i++) {
        for (std::size_t j = 0; j < arr.columns(); j++) {
            arr[i][j] = i * 10 + j;
        }
    }

    for (std::size_t i = 0; i < arr.rows(); i++) {
        // you can use the array element 'size()' function instead of 'columns()'
        for (std::size_t j = 0; j < arr[i].size(); j++) {
            std::cout << arr[i][j] << " ";
        }
        std::cout << std::endl;
    }
}
0

1) Да, вы могли бы просто позвонить free()

Но обратите внимание, что вы выполняете сглаживание указателей (2 указателя на разные типы, int и int [] с тем же адресом), что может вызвать тонкие ошибки оптимизации. И в C++ очень плохая практика использования malloc(), а numcols должны быть const.

2) Способ, которым вы можете это сделать в C++, будет использовать [<array>][2] если размер будет известен во время компиляции:

     array<array<int, 4>,2> a;

Более гибкой альтернативой является использование векторов, которые обеспечивают динамический размер и изменение размера:

     vector <vector <int>> b(2, vector<int>(4)); 

3) С новым вы также можете сделать:

    p = new (int[2][4]);

Первое измерение также может быть переменным, но второе должно быть константой. Но я бы посоветовал вам использовать одну из стандартных альтернативных альтернатив.

0

Вы не можете сделать это в C++. Ваш код malloc() отлично действует C, но недействителен C++. И это не сработает с new.

C++ требует, чтобы типы массивов имели постоянный размер, C допускает типы массивов динамического размера. Существует только исключение для 1D массивов, которые могут быть выделены динамическим размером в C++, но это. В 2D-массиве второй размер должен быть известен во время компиляции.

Это тот момент, когда C намного сильнее, чем C++.


Требуется немного, чтобы убедить g++ следовать стандарту в этом отношении, но составление этой небольшой программы

#include <stdlib.h>

int main(int argc, char** args) {
    int (*foo)[argc];
}

с g++ -pedantic -std=C++11 foo.cpp добросовестно выдает сообщение об ошибке:

foo.cpp: In function ‘int main(int, char**):
foo.cpp:4:17: warning: ISO C++ forbids variable length array ‘foo [-Wvla]
  • 0
    Когда вы говорите «не могу сделать это в c ++», вы имеете в виду «не могу сделать это с помощью нового»? Вставленный мною код был скомпилирован с использованием g ++, а malloc является частью c ++.
  • 0
    Проблема в типе, а не в вызове malloc() . malloc() прекрасно доступна на обоих языках, но тип int (*)[some dynamic size] не существует в C ++. Смотрите мое редактирование.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню