Функция создания двумерного динамического массива. С++
Пытаюсь создать функцию типа void для создания двумерного динамического массива и создать в функции main какой-нибудь указатель для быстрого доступа к этому двумерному массиву, в итоге получаю кучу ошибок. Понимаю, что легче было бы это сделать через тот же тип double, но мне уже интересно, возможно ли это через void?
using namespace std;
void Array(unsigned int rows, unsigned int colms)
{
double** array2d = new double* [rows];
for (unsigned int i = 0; i < rows; i++)
array2d[i] = new double[colms];
}
int main()
{
// 1. Создание двумерного массива
unsigned int numRows = 4;
unsigned int numCols = 10;
void (*list)(unsigned int, unsigned int) = Array;
// 2. Инициализация двумерного массива
int data = 0;
for (unsigned int i = 0; i < numRows; i++)
for (unsigned int j = 0; j < numCols; j++)
{
list[i][j] = data;
data++;
}
// 3. Выводим двумерный массив в консоль
for (unsigned int i = 0; i < numRows; i++)
{
for (unsigned int j = 0; j < numCols; j++)
cout << list[i][j] << " ";
cout << endl;
}
// 4. Освобождаем память
for (unsigned int i = 0; i < numRows; i++)
{
double* p_row = list[i];
cout << i << ": " << p_row;
delete[] p_row;
cout << " -(delete[] p_row)-> " << p_row;
p_row = nullptr;
cout << " -(p_row = nullptr)-> " << p_row << endl;
}
delete[] list;
list = nullptr;
return 0;
}
Ответы (3 шт):
Вы создали "вещь в себе" — функция Array
действительно создает массив, который благополучно теряется. Похоже, вы не разобрались, как работать с функциями. Ваше void (*list)(unsigned int, unsigned int) = Array;
— не создание массива, это - указатель на функцию, так что все ваши обращения как к массиву list[]
просто нонсенс.
double** Array(unsigned int rows, unsigned int colms)
{
...
return array2d;
}
...
double **list = Array(numRows,numCols);
Можно и через void*
, но что это дает? Все равно вы выделяете память для массива double
, так что кроме как к типу double**
привести результат будет больше не к чему - так зачем эти приведения, которых можно избежать?
Вы конечно понаписали, что больно смотреть, и double тоже не поможет при возврате из функции.
Так же вам стоит почитать про передачу параметров в функцию:
- по значению
- по ссылке
- по указателю
Можете почитать тут. Пропустим разбор вашего кода, просто покажу как можно было бы это реализовать:
#include <iostream>
double** create_arr(int rows, int colms){
double **arr = new double*[rows];
for (int i(0); i < rows; i++){
arr[i] = new double[colms];
}
return arr;
}
void init(double **arr,int rows, int colms){
for (int i(0); i < rows; i++){
for (int j(0); j < colms; j++)
{
arr[i][j] = i + j;
}
}
}
void printArr(double *arr[],int rows, int colms){
for (int i(0); i < rows; i++){
std::cout << std::endl;
for (int j(0); j < colms; j++){
std::cout << arr[i][j] << " ";
}
}
}
int main(){
int row = 4, col = 4;
double **arr = create_arr(row, col);
init(arr, row, col);
printArr(arr, row, col);
}
Как и говорили уже можно использовать void*, но это не имеет смысла, т.к. все равно придется использовать приведение типов.
Понимаю, что легче было бы это сделать через тот же тип double, но мне уже интересно, возможно ли это через void?
Это ложная, кажущаяся лёгкость:
- Сложно удалять, забыл удалить - утечка памяти. Полное применение идиомы RAII (получение ресурса есть инициализация...) - очень часто, очень неплохой выбор;
- Лишний расход памяти;
- Соответственно, для современных ЦП, у которых доступ к памяти самое дорогое, невысокая производительность;
- Плюс создание/удаление требуют
rows+1
операций выделения/освобождения памяти, что тоже весьма и весьма не шустро. Хотя это можно и исправить, но ценой ещё большего усложнения.
Насчёт желания void
, это ваше желание, в принципе, - правильное. Путь C++ - отделить типы от алгоритмов. Только вот не void
, но аргумент шаблона.
darr.cpp:
#include <iostream>
// Демонстрационный аналог динамических массивов C (variable length array)
// T x[r][c];
template<class T>
class DemoMatrix {
size_t rows; // Не используется, для будущих расширений.
size_t colms;
T *matrix;
public:
DemoMatrix(size_t _rows, size_t _colms) :
rows(_rows), colms(_colms)
{
matrix = new T[rows*colms];
}
~DemoMatrix() {
delete[] matrix;
}
T *operator[](size_t i) {
return matrix + i*colms;
}
};
int main() {
const unsigned numRows = 4;
const unsigned numCols = 10;
DemoMatrix<double> list(numRows, numCols);
for(unsigned i = 0; i < numRows; i++) {
for(unsigned j = 0; j < numCols; j++) {
list[i][j] = j + i;
}
}
list[1][3] += 1.2;
std::cout << list[1][3] << ' ' << list[3][1] << std::endl;
}