Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.11.2012, 23:44   #1
SAMOUCHKA
Форумчанин
 
Регистрация: 07.08.2011
Сообщений: 576
По умолчанию динамический двумерный массив- возможен-ли?

вопрос ясен из заголовка. Возможен в С++ динамический, двумерный массив? Если да, как это будет выглядеть?
Дело в том что есть ф-ции принимающие двумерный массив, но размер его изначально неизвестен.
SAMOUCHKA вне форума Ответить с цитированием
Старый 23.11.2012, 00:10   #2
pproger
C++ hater
Старожил
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

возможен. как одномерный динамический массив указателей. либо как вектор векторов.
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Старый 23.11.2012, 00:25   #3
kineziz
Форумчанин
 
Регистрация: 22.12.2011
Сообщений: 378
По умолчанию

Создание:
Код:
int** DynamicArray = new int*[CountString];
for (short i = 0; i < CountString; ++i)
      DynamicArray[i] = new int[CountColumn];
Удаление:
Код:
int** DynamicArray = new int*[CountString];
for (short i = 0; i < CountString; ++i)
     delete [] DynamicArray[i];
delete [] DynamicArray;
Большинство хороших программистов делают свою работу не потому, что ожидают оплаты или признания, а потому что получают удовольствие от программирования.

Последний раз редактировалось kineziz; 23.11.2012 в 00:31.
kineziz вне форума Ответить с цитированием
Старый 23.11.2012, 13:22   #4
SAMOUCHKA
Форумчанин
 
Регистрация: 07.08.2011
Сообщений: 576
По умолчанию

Цитата:
Сообщение от kineziz Посмотреть сообщение
Создание:
Код:
int** DynamicArray = new int*[CountString];
for (short i = 0; i < CountString; ++i)
      DynamicArray[i] = new int[CountColumn];
Удаление:
Код:
int** DynamicArray = new int*[CountString];
for (short i = 0; i < CountString; ++i)
     delete [] DynamicArray[i];
delete [] DynamicArray;
при передаче такого массива в функцию, само собой возникает ошибка.

фот прототип функции
Код:
void func(int array[][3]);
размер второго индекса всегда равен трем, а вот размер первого изначально не известен.


Цитата:
либо как вектор векторов.
а как это синтаксически выглядит? и можно-ли будет этот вектор векторов передать выше описанной функции?
Но наверно тоже не получится в прототипе тип int, а тут тип vector
SAMOUCHKA вне форума Ответить с цитированием
Старый 23.11.2012, 14:05   #5
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,091
По умолчанию

вектор векторов - это ужас при периодическом изменении размерностей.
Выглядит это чудо так: vector < vector < int> >
Что мешает написать "класс-обёртку" над int**, чтобы там еще и размерность хранилась и легко было передавать в классы? Или можно поискать что-то готовое, должно же быть.
pu4koff вне форума Ответить с цитированием
Старый 23.11.2012, 19:49   #6
pproger
C++ hater
Старожил
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2pu4koff
Цитата:
вектор векторов - это ужас при периодическом изменении размерностей.
ну тут как бэ выбор невелик. если стала известна размерность - можно установить векторам capacity. если какой-либо вектор будет изменен, то только он сожмется/расширится в памяти.
а так использование любого вектора можно назвать ужасом при периодическом изменении размерности

Цитата:
Что мешает написать "класс-обёртку" над int**
мартышкин труд. готов поспорить, что даже более-менее нетривиальная реализация будет ничуть не лучше вектора векторов, если предположить, что подход будет аналогичный векторному (хранение данных в непрерывной области памяти). выйграть можно лишь написав специфичную для задачи структуру данных. но даже тут достаточно реализовать свой аллокатор и адаптер интерфейса над тем же вектором
тем более, судя по вопросу автора, вектор векторов ему вполне подойдет
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Старый 23.11.2012, 23:47   #7
Suby
Пользователь
 
Аватар для Suby
 
Регистрация: 03.11.2012
Сообщений: 89
По умолчанию

Цитата:
Сообщение от pproger Посмотреть сообщение
2pu4koff


ну тут как бэ выбор невелик. если стала известна размерность - можно установить векторам capacity. если какой-либо вектор будет изменен, то только он сожмется/расширится в памяти.
а так использование любого вектора можно назвать ужасом при периодическом изменении размерности


мартышкин труд. готов поспорить, что даже более-менее нетривиальная реализация будет ничуть не лучше вектора векторов, если предположить, что подход будет аналогичный векторному (хранение данных в непрерывной области памяти). выйграть можно лишь написав специфичную для задачи структуру данных. но даже тут достаточно реализовать свой аллокатор и адаптер интерфейса над тем же вектором
тем более, судя по вопросу автора, вектор векторов ему вполне подойдет
Я протекла!
Suby вне форума Ответить с цитированием
Старый 24.11.2012, 00:12   #8
SAMOUCHKA
Форумчанин
 
Регистрация: 07.08.2011
Сообщений: 576
По умолчанию

а задача, еще раз ровторю следующая:
есть функция, в заголовочном файле ее рототип выглядит примерно так:
void func(int [][3]);
так вот размер первого индекса, передоваемого в функцию массива, не известен. Вообще он в процессе работы будет менятся
SAMOUCHKA вне форума Ответить с цитированием
Старый 24.11.2012, 00:21   #9
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от SAMOUCHKA Посмотреть сообщение
вопрос ясен из заголовка. Возможен в С++ динамический, двумерный массив? Если да, как это будет выглядеть?
Дело в том что есть ф-ции принимающие двумерный массив, но размер его изначально неизвестен.
Нет не возможен. В языке с++ вообще нет никаких динамических массивов.

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

Можно получить указатель на непрерывный блок памяти, выделенный в куче, и привести его к типу "ссылка на массив", и работать, как с обычным массивом.

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

Последний раз редактировалось _Bers; 24.11.2012 в 01:13.
_Bers вне форума Ответить с цитированием
Старый 24.11.2012, 00:58   #10
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от SAMOUCHKA Посмотреть сообщение
а задача, еще раз ровторю следующая:
есть функция, в заголовочном файле ее рототип выглядит примерно так:
void func(int [][3]);
так вот размер первого индекса, передоваемого в функцию массива, не известен. Вообще он в процессе работы будет менятся
Если есть готовая функция, и менять её прототип нельзя, значит нужно изменить тип подгоняемого под функцию аргумента.

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

http://ideone.com/4kzHyM

Код:
#include <iostream>
 
//аргументом функции насамом деле 
//является ссылка на массив, а не массив по значению
void Func(int array[][3])
{
    std::cout<<"func starting...\n";
    for(size_t n=0;n<4;++n)
    {
        for(size_t i=0;i<3;++i) { std::cout<< array[n][i]<<" ";  }
        std::cout<< "\n";
    }
}
 
int main()
{
    //сначала стандартный юзкейс двухмерных массивов
    int a[][3] = { {1,2,3},{1,2,3},{1,2,3},{1,2,3} };
    Func(a);
 
    //эквивалентный массив, только с явным указанимем размерности
    int b[4][3] = { {1,2,3},{1,2,3},{1,2,3},{1,2,3} };
    Func(b);
 
    //эквивалент для случая работы с динамической памятью
    int* ptr = new int[4*3]; //выделяем на куче блок эквивалентный int[4][3]
    
    //заполняем его теми же элементами, что и в случае с обычным двухмерным массивом
    ptr[0] = 1; ptr[1]  = 2; ptr[2]  = 3;
    ptr[3] = 1; ptr[4]  = 2; ptr[5]  = 3;
    ptr[6] = 1; ptr[7]  = 2; ptr[8]  = 3;
    ptr[9] = 1; ptr[10] = 2; ptr[11] = 3;
 
    //приводим int* к типу указателя на двухмерный массив
    int (*pAr)[4][3] = (int (*)[4][3]) ptr;
 
    //приведение типа указетеля на двухмерный массив, к ссылке на двухмерный массив
    int (&rAr)[4][3]= *pAr;
 
    Func(rAr);
 
    delete[] ptr;
 
    //эквивалент для случая работы с динамической памятью, но без явного указания количества элементов
    {
        int* ptr = new int[4*3]; //выделяем на куче блок эквивалентный int[4][3]
        
        //заполняем его теми же элементами, что и в случае с обычным двухмерным массивом
       ptr[0] = 1; ptr[1]  = 2; ptr[2]  = 3;
       ptr[3] = 1; ptr[4]  = 2; ptr[5]  = 3;
       ptr[6] = 1; ptr[7]  = 2; ptr[8]  = 3;
       ptr[9] = 1; ptr[10] = 2; ptr[11] = 3;
 
        //приводим int* к типу указателя на двухмерный массив
        int (*pAr)[][3] = (int (*)[][3]) ptr;
 
        //приведение типа указетеля на двухмерный массив, к ссылке на двухмерный массив
        int (&rAr)[][3]= *pAr;
 
        Func(rAr);
 
        delete[] ptr;
    }
    
    return 0; 
}

Последний раз редактировалось _Bers; 24.11.2012 в 01:09.
_Bers вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
динамический двумерный массив Ирина561 Помощь студентам 4 10.02.2012 15:30
динамический двумерный массив Ilya_L Помощь студентам 3 28.09.2011 04:29
Двумерный динамический массив Sauber Помощь студентам 2 22.03.2011 08:02
Двумерный динамический массив Markuss Помощь студентам 6 07.12.2010 09:29
Двумерный динамический массив С++ UnknownVirus Помощь студентам 7 20.06.2010 01:48