Форум программистов, компьютерный форум CyberForum.ru

Массив: каким образом можно изменить размер многомерного массива - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.70
Shaman163
4 / 4 / 0
Регистрация: 22.12.2011
Сообщений: 134
26.03.2013, 19:25     Массив: каким образом можно изменить размер многомерного массива #1
Я на 100% уверен что вопрос неоднократно поднимался до меня, поэтому заранее прошу прощения за эту тему..
Я просто ни как не могу найти того чего ищу.
Вопрос в следующем:
каким образом можно изменить размер многомерного массива???
То есть:
C++
1
Byte result[8192][8192];
в дальнейшем мне нужно изменить обе мерности массива.

+ Совершенно постыдный вопрос
как же всё таки создать массив с заранее неизвестной размерностью
Например:
C++
1
2
3
int pointNum = 200;
//...
Point ptArray[pointNum];
Появляется ошибка что pointNum не является константным значением,
однако при следующем случае ошибка не исчезает.
C++
1
2
3
const int pointNum2 = pointNum;
//...
Point ptArray[pointNum];
PS
QT не предлагать, пишу на голых плюсах.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.03.2013, 19:25     Массив: каким образом можно изменить размер многомерного массива
Посмотрите здесь:

C++ Каким образом можно записать стек и очередь в дек
Каким образом можно осуществить загрузку файла из интернета по url ? C++
C++ Каким образом можно сделать выключение компютера С++
В массиве найти наибольший элемент. После этого изменить исходный массив следующим образом: у всех элементов массива, C++
C++ Каким образом getchar() меняет содержимое массива?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Olivеr
 Аватар для Olivеr
411 / 407 / 13
Регистрация: 06.10.2011
Сообщений: 830
26.03.2013, 20:11     Массив: каким образом можно изменить размер многомерного массива #2
Цитата Сообщение от Shaman163 Посмотреть сообщение
как же всё таки создать массив с заранее неизвестной размерностью
Одномерный:
C++
1
2
3
4
5
6
    size_t arr_size = 100;
    int *arr = new int[arr_size];
    //...
    arr[0] = 0;
    //...
    delete arr;
Двумерный:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
    unsigned col_count = 3; //количество столбцов
    int **dyn_arr = new int*[col_count];
 
    unsigned str_count = 2; //кол-во строк
 
    for (size_t i = 0; i!=col_count; i++)
        dyn_arr[i] = new int[str_count]; //создаем столбцы
 
    //dyn_arr[str][col] - используем вот такую запись
 
    dyn_arr[0][0] = 1;
    dyn_arr[0][1] = 2;
    dyn_arr[0][2] = 3;
 
    dyn_arr[1][0] = 4;
    dyn_arr[1][1] = 5;
    dyn_arr[1][2] = 6;
 
    for (size_t i = 0; i!=str_count; i++,cout<<endl)
        for (size_t j = 0; j!=col_count; j++)
            cout<<dyn_arr[i][j]<<"\t";
 
    for (size_t i = 0; i!=col_count; i++)
        delete[] dyn_arr[i]; //удаляем из дин. памяти
 
    delete[] dyn_arr;//удаляем
Добавлено через 1 минуту
Цитата Сообщение от Shaman163 Посмотреть сообщение
каким образом можно изменить размер многомерного массива???
и меня этот вопрос интересует. ничего на ум, кроме как создавать новый массив с нужной размерностью и заливать в него элементы, не приходит. нужна какая-нибудь функция урезания памяти...

Добавлено через 2 минуты
Погуглил и нашел несколько решений:
C++
1
2
3
4
5
int * pArray = new int[10];
void resize(size_t newSize)
{
    int * pArray = (int *) realloc(pArray, newSize);
}
C++
1
2
3
4
5
6
7
8
9
10
void resize() {
    size_t newSize = size * 2;
    int* newArr = new int[newSize];
 
    memcpy( newArr, arr, size * sizeof(int) );
 
    size = newSize;
    delete [] arr;
    arr = newArr;
}
И то о чем я говорил:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
int size = 10;
int* arr = new int[size];
 
void resize()
{
   int* resize_arr = new int[size + 1];
   for(int i = 0; i < size; i++)
        resize_arr[i] = arr[i];
 
   size++;
   arr = resize_arr;
   delete[] resize_arr;
}
Shaman163
4 / 4 / 0
Регистрация: 22.12.2011
Сообщений: 134
26.03.2013, 20:15  [ТС]     Массив: каким образом можно изменить размер многомерного массива #3
Спасибо конечно, но вы меня немного не поняли
мне не нужно добавлять или убавлять размерность массива
а просто изменить его размерность не взирая на значения
вот как я это делал в C#
C#
1
2
int[2][2] bla;
bla = new int[50][50];
то есть изменить содержимое того же массива
rangerx
1908 / 1517 / 139
Регистрация: 31.05.2009
Сообщений: 2,876
26.03.2013, 20:50     Массив: каким образом можно изменить размер многомерного массива #4
Используйте std::vector вместо массивов.
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,269
26.03.2013, 21:13     Массив: каким образом можно изменить размер многомерного массива #5
Тут чуть больше писать надо. Например так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int main () {
  int**p;
  int array [5][6];
  
  p= (int**)array;
  //Теперь p это фактически  array [5][6], можешь написать:
  //p[5][6]= 100; И тебе ничего за это не будет
  
  //Ну и дальше:
  int array_1 [100][200];
  p= (int**)array_1;
 
  int array_2 [33][44];
  p= (int**)array_2;
 
  int array_3 [55][66];
  p= (int**)array_3;
           
  return 0;
}
Можно и другие варианты использовать. Но это не главное. Главное, что значения из array не становятся значениями array_1, а те, в свою очередь не станут значениями array_2 и так далее. То есть просто напросто p указывает всякий раз на новый участок памяти с НУЖНОЙ размерностью, но с совершенно другими значениями нежели были. Это надо учитывать. И если хочешь чтобы при изменении размерности массива сохранились его значения, это надо будет делать вручную.
rangerx
1908 / 1517 / 139
Регистрация: 31.05.2009
Сообщений: 2,876
27.03.2013, 05:14     Массив: каким образом можно изменить размер многомерного массива #6
Не думаю, что человеку ищущему аналог конструкции из C# и не владеющему в достаточной степени C++ следует советовать использовать указатели. Тем более что приведённый пример создания двумерного динамического массива является некорректным, т.к. не учитывается возможность возникновения и обработки исключений(потенциальная утечка памяти). К тому же, перепутаны строки со столбцами... Пример с указателем на указатель(предыдущий пост) также не является корректным. Указатель на указатель и двумерный массив, это абсолютно разные вещи, и делать так, как показано выше нельзя.
Самый простой и безопасный вариант, как я уже и сказал, использовать std::vector
C++
1
2
3
4
5
6
#include <vector>
//...
typedef std::vector<int> IntVector;
//...
std::vector<IntVector> a(2, IntVector(2));
a = std::vector<IntVector>(50, IntVector(50));
P.S. eстественно, если хочется придать коду более благородный вид, лучше спрятать всё это дело внутри шаблонного класса.
UnsKneD
алкокодер
 Аватар для UnsKneD
153 / 149 / 11
Регистрация: 27.12.2012
Сообщений: 548
27.03.2013, 06:34     Массив: каким образом можно изменить размер многомерного массива #7
Немного тормознутый способ с переливаниями.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void swop( int *A, int *B, int i){
    for( int j = 0; j<i; j++){ 
        A[j] = B[j];
    };
};
 
void del( int *A ){
    delete []A; A = 0;
}
 
int main()
{ 
    const int N = 65535; //max для int 2^16 - 1 = 65535
    int *A = new int[1];
 
    for(int i = 1; i<=N; i++){
        A[i-1] = i;
        int *B = new int[i];
        swop(B,A,i);
        del( A );
        A = new int[i+1];
        swop(A,B,i);
        del( B );
    }
    del( A );
 
    return 0;
}
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,269
27.03.2013, 14:47     Массив: каким образом можно изменить размер многомерного массива #8
Цитата Сообщение от rangerx Посмотреть сообщение
Пример с указателем на указатель(предыдущий пост) также не является корректным. Указатель на указатель и двумерный массив, это абсолютно разные вещи, и делать так, как показано выше нельзя.
Сказать всё, что угодно можно. Там единственная у меня ошибка- в комментариях полез за пределы массива, но она к теме не имеет отношениях.
rangerx
1908 / 1517 / 139
Регистрация: 31.05.2009
Сообщений: 2,876
27.03.2013, 20:02     Массив: каким образом можно изменить размер многомерного массива #9
kravam, двумерный массив в C\С++, имеет ту же структуру, что и одномерный, т.е. все элементы в нём расположены последовательно друг за другом. Проверить это можно с помощью следующего примера
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
 
int main()
{
    const int m = 3;
    const int n = 4;
 
    int a[m][n] =
    {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9 ,10, 11, 12}
    };
 
    int* p = (int*) a;
 
    const int len = (m * n);
    for(int i = 0; i < len ; ++i)
        std::cout << p[i] << ' ';
    std::cout << '\n';
}
в двумерный он превращается с помощью простой формулы i * n + j
C++
1
2
3
4
5
6
7
8
9
for(int i = 0; i < m ; ++i)
{
    for(int j = 0; j < n ; ++j)
    {
        std::cout.width(4);
        std::cout << p[i * n + j];
    }
    std::cout << '\n';
}
Нельзя приводить имя массива, которое по сути является адресом его первого элемента, к указателю на указатель(типу предназначенному для хранение адресов других указателей), а затем пытаться его разыменовать.
C++
1
2
3
4
5
int a[m][n];
int* p1 = (int*) a;
int** p2 = (int**) a;
p1[0]; // Первый элемент массива
p2[0]; // Указатель, который в качестве адреса хранит значение первого элемента массива...
Думаю не нужно объяснять, что произойдёт, при попытке разыменования p2[0]
C++
1
p2[0][0]; // берём значение по адресу p2[0], в то время как "адрес", это число являющееся первым элементом массива(!)
Shaman163
4 / 4 / 0
Регистрация: 22.12.2011
Сообщений: 134
28.03.2013, 14:50  [ТС]     Массив: каким образом можно изменить размер многомерного массива #10
Блин, ребят не могу уже, помогите вернуть массив из библиотеки.
Немного подумав пришёл к выводу что на весь класс нужно использовать 1 глобальный массив "result"
который в итоге я и буду вытаскивать из библиотеки.
на данный момент код выглядит вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// .h файл
    public class SquareMatrix
    {
        public:
        void CellularNoiseMap(int Size, int pointNum, int seed);
        Byte result[8192][8192];
           }
//.cpp собственно сам класс
    void SquareMatrix::CellularNoiseMap(int Size, int pointNum, int seed)
    {
        Random rnd(seed);
        int cellSize = Size / pointNum;
        int xBuffer = 0;
        int yBuffer = 0;
        Point* ptArray = new Point[size_t(pointNum)];
 
        for (int x = 0, step = 0; x != pointNum * pointNum; x++)
        {
            ptArray[x] = Point(rnd.Next(xBuffer, xBuffer + cellSize), rnd.Next(yBuffer, yBuffer + cellSize));
            xBuffer += cellSize;
            step++;
            if (step == pointNum)
            {
                yBuffer += cellSize;
                xBuffer = 0;
                step = 0;
            }
        }
 
        for(int x=0;x!=Size;x++)
            for(int y=0;y!=Size;y++)
            {
                    int minDist = INT_MAX;
                    for (int xx = 0; xx != pointNum * pointNum; xx++)
                    {
                        int dist = (int)sqrt(pow((float)ptArray[xx].X - x, 2) + pow((float)ptArray[xx].Y - y, 2));
                        int dist2;
 
                        int dx = abs(x - ptArray[xx].X);
                        int dy = abs(y - ptArray[xx].Y);
                        if (dx > Size / 2)
                            dx = Size - dx;
                        if (dy > Size / 2)
                            dy = Size - dy;
 
                        dist2 = (int)sqrt((float)(dx * dx + dy * dy));
 
                        if (minDist > dist)
                            minDist = dist;
                        if (minDist > dist2)
                            minDist = dist2;
                    }
 
                    int tmp = (int)((float)minDist / cellSize * 255);
                    if (tmp > 255)
                        tmp = 255;
                    result[x][y] = (Byte)tmp;
            }
    }
Но! как можно догадаться ни метод, ни массив невидимы снаружи библиотеки.
Проблема решается использованием модификатора ref, но в таком случае студия начинает ругаться на массив.
Говоря что то вроде - "использование стандартных массивов в управляемом классе невозможно".
Как итог - я в безвылазном тупике..
PS:
я использую фиксированную длинну массива в 8192, но это не совсем то что мне нужно.
По логике вещей, при вызове длинна массива должна изменятся на размерность "int Size"
avfed
14 / 12 / 2
Регистрация: 24.01.2013
Сообщений: 23
28.03.2013, 15:58     Массив: каким образом можно изменить размер многомерного массива #11
динамический двухмерный массив делается так:
C++
1
2
3
4
5
6
7
    int siz=5;
    int** p;
    p=new int*[siz];
    for(int i=0;i<siz;i++)
    {
        p[i]=new int[siz];
    }
единственное придется текущую размерность хранить, лучше наверное в приватной области как и int** p (вместо Byte result[8192][8192]) если нужно изменить размерность проще всего будет сделать процедурку которая будет на входе и на выходе иметь int**, а внутри уже будет или обрезание или пересоздание, как вам удобнее

ну или не иметь гемороя и использовать vector
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,269
28.03.2013, 15:58     Массив: каким образом можно изменить размер многомерного массива #12
Был неправ
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
 
#define stolb 5
#define strok 6
 
int main () {
 
  int array [stolb][strok];
 
 
  int**p;
  int* p_ [stolb];
  p= &p_[0];
  for (int i= 0; i< stolb; i++) 
      p_[i]= array [i];
  
 
  array [0][0]= 100;
  printf ("%x\n", array [0][0] );
  printf ("%x\n", p [0][0] );
 
  getchar ();
           
  return 0;
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.03.2013, 16:14     Массив: каким образом можно изменить размер многомерного массива
Еще ссылки по теме:

Новичок С++, каким образом можно в функцию включить динамический массив? C++
Можно ли каким-то образом наследовать тип bool C++
Дан динамический одномерный массив размера N, изменить размер массива до M C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
avfed
14 / 12 / 2
Регистрация: 24.01.2013
Сообщений: 23
28.03.2013, 16:14     Массив: каким образом можно изменить размер многомерного массива #13
эмм, а в чем великий философский смысл?, основная то идея как раз обойтись без предопределенных констант
Yandex
Объявления
28.03.2013, 16:14     Массив: каким образом можно изменить размер многомерного массива
Ответ Создать тему
Опции темы

Текущее время: 23:07. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru