Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.54/13: Рейтинг темы: голосов - 13, средняя оценка - 4.54
0 / 0 / 0
Регистрация: 22.05.2017
Сообщений: 8
1

Как создать двумерный динамический массив на указателях?

28.05.2018, 18:05. Показов 2358. Ответов 11
Метки нет (Все метки)

Имеется вот такой код, но если поставить **b[j][i] выбивает ошибку;
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
unsafe public static void smejn()
            {
                int kol = 2;
                int**[] b = new int**[kol]; 
                int*[] a = new int*[kol];
                int[] one = new int[kol];
                one[0] = 1;
                one[1] = 2;
 
                fixed (int** p1 = a)
                {
                    for (int i = 0; i < kol; i++)
                    {
                        b[i] = p1+i;
 
                        fixed (int* p = one)
                        {
                            for (int j = 0; j < kol; j++)
                            {
                                a[j] = p + j;
                                Console.Write("Address: 0x{0}", new IntPtr(b[j][i]).ToString("X")+*b[j][i]);
                            }
                            Console.WriteLine();
 
                        }
                    }
                    
                }
 
 
 
            }
Вообщем, я в ступоре.
0

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

Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.05.2018, 18:05
Ответы с готовыми решениями:

Как создать двумерный динамический массив
Как создать двумерный массив на C# (размерность неизвестна, вычисляется в ходе работы программы) и...

Как создать двумерный динамический массив или список?
как создать двумерный динамический массив или список?

Создать динамический двумерный массив целых чисел
Помогите создать динамический двумерный массив целых чисел (матрица) Базовый класс с выводом...

Создать двумерный динамический массив типа int
Как создать двумерный ДИНАМИЧЕСКИЙ массив типа int.

11
322 / 301 / 173
Регистрация: 16.11.2010
Сообщений: 1,069
Записей в блоге: 9
29.05.2018, 09:48 2
Цитата Сообщение от alexmelk Посмотреть сообщение
Как создать двумерный динамический массив на указателях?
Сомневаюсь, что fixed позволяет работать с двумерными массивами

В качестве альтернативы советую воспользоваться, например, stackalloc:
C#
1
int** a = stackalloc int*[6];//двумерный динамический массив статических массивов
Либо если очень надо в куче, то
C#
1
2
                int** a = (int**)Marshal.AllocHGlobal(3 * 6);  //получился двумерный массив [3,6]
                *(*(a + 2) + 2) = 5;                           //эквивалент a[2][2] = 5 и в таком духе
Но не забудь потом после всех манипуляций вызвать Marshal.FreeHGlobal для a.
1
0 / 0 / 0
Регистрация: 22.05.2017
Сообщений: 8
29.05.2018, 18:53  [ТС] 3
Ухты)
Второй метод то, что надо))
Но он работает через раз, и в этот раз результат выдаёт корректный. Использовал очистку. Пишет, что память повреждена.
C#
1
2
3
4
5
6
7
8
unsafe
{
  int kol = 4;
  b = (int**)Marshal.AllocHGlobal(kol * kol);  
  (*(*(b + 2) + 2)) = 5;
  MessageBox.Show( (*(*(b + 2) + 2) ).ToString());
  Marshal.FreeHGlobal((IntPtr)b);
}
b у меня глобальная;

Добавлено через 8 минут
netBool, но Вы же наверняка знаете в чём проблема)
0
322 / 301 / 173
Регистрация: 16.11.2010
Сообщений: 1,069
Записей в блоге: 9
29.05.2018, 19:04 4
Цитата Сообщение от alexmelk Посмотреть сообщение
b у меня глобальная;
В этом, видимо, и проблема. Как вы ее объявляете?
0
0 / 0 / 0
Регистрация: 22.05.2017
Сообщений: 8
29.05.2018, 19:09  [ТС] 5
Вот так:
C#
1
public static unsafe int** b;
но делал и вот так:
C#
1
int** b = (int**)Marshal.AllocHGlobal(kol * kol);
и результат работы одинаковый, странно.
0
322 / 301 / 173
Регистрация: 16.11.2010
Сообщений: 1,069
Записей в блоге: 9
29.05.2018, 19:12 6
Глобальную переменную можно использовать так:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
        static IntPtr bs;
        static void Main(string[] args)
        {
            unsafe
            {
                int kol = 4;
                bs = Marshal.AllocHGlobal(kol * kol);
                int** b = (int**)bs;
 
                (*(*(b + 2) + 2)) = 5;
                Console.WriteLine((*(*(b + 2) + 2)).ToString());
 
                b[1][1] = 4;
                Console.WriteLine(b[1][1]);
 
                Marshal.FreeHGlobal(bs);//с этиго моменты bs становится невалидным
            }
                        
            Console.ReadKey();
 
        }
Добавлено через 2 минуты
Цитата Сообщение от alexmelk Посмотреть сообщение
и результат работы одинаковый, странно.
C#
1
2
3
4
5
6
7
8
unsafe
{
  int kol = 4;
  int** b = (int**)Marshal.AllocHGlobal(kol * kol);  
  (*(*(b + 2) + 2)) = 5;
  MessageBox.Show( (*(*(b + 2) + 2) ).ToString());
  Marshal.FreeHGlobal((IntPtr)b);
}
такой код работает, как часы
0
0 / 0 / 0
Регистрация: 22.05.2017
Сообщений: 8
29.05.2018, 19:27  [ТС] 7
У Вас код работает?
Просто у меня нет, неужели что-то с Visual Studio ?
Как создать двумерный динамический массив на указателях?
0
0 / 0 / 0
Регистрация: 22.05.2017
Сообщений: 8
29.05.2018, 19:40  [ТС] 8
Вообщем, спасибо))
0
322 / 301 / 173
Регистрация: 16.11.2010
Сообщений: 1,069
Записей в блоге: 9
29.05.2018, 20:50 9
Лучший ответ Сообщение было отмечено alexmelk как решение

Решение

Цитата Сообщение от alexmelk Посмотреть сообщение
У Вас код работает?
Просто у меня нет, неужели что-то с Visual Studio ?
В общем запустил раз 10 и тоже ошибку выдало. Короче, помозговал, как это все происходит в памяти и понял, что накосячил))

У меня получилось создать двумерный динамический (по факту динамический массив динамических массивов). 10 из 10 запусков прошло успешно. Но выглядит это не так красиво, как раньше)))

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
            unsafe
            {
 
                int* a = (int*)Marshal.AllocHGlobal(4);
 
                int* a1 = (int*)Marshal.AllocHGlobal(3);
                int* a2 = (int*)Marshal.AllocHGlobal(3);                
 
                *a = (int)a1;
                *(a+1) = (int)a2;
 
                int** b = (int**)a;
                b[1][1] = 5;
 
                Console.WriteLine(b[1][1]);
 
                Marshal.FreeHGlobal((IntPtr)a);
                Marshal.FreeHGlobal((IntPtr)a1);
                Marshal.FreeHGlobal((IntPtr)a2);
            }
Вот примерно такой расклад. При этом FreeHGlobal надо прописать для каждого массива. Это не оч удобно. Поэтому лучше сразу сделать для них какую-то оболочку, чтобы в цикле сразу пройтись по всем и удалить. Например (не тестил):
C#
1
2
3
4
5
6
7
8
9
MyFreeHGlobal(int** ar, m, n)
{
       for (int i=0;i<m;i++){
             for (int i=0;i<n;i++){
                    Marshal.FreeHGlobal((IntPtr)ar[m,n]);
             }
       }
       Marshal.FreeHGlobal((IntPtr)ar);
}
где m, n - размерность нашего двумерного динамического
1
0 / 0 / 0
Регистрация: 22.05.2017
Сообщений: 8
29.05.2018, 22:04  [ТС] 10
Работает чётко, спасибо!
(насчёт очистки сомневаюсь)
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
 class Program
    {
        static IntPtr bs;
        static void Main(string[] args)
        {
            unsafe
            {
                int m = 5; //столбцы
                int n = 10; //строки
                Random r = new Random();
                int* a = (int*)Marshal.AllocHGlobal(m);
                int* a1 =(int*)Marshal.AllocHGlobal(m);
 
                //Инициализация;
                for (int i = 0; i < n; i++)
                {
                    for (int j = 0; j < m; j++)
                    {
                        a1 = (int*)Marshal.AllocHGlobal(m);
                        *(a + i) = (int)a1;
                    }
                }
 
                int** bs = (int**)a;
 
                //Забиваем массив элементами;
                for(int i = 0; i < n; i++)
                {
                    for(int j = 0; j < m; j++)
                    {
                        bs[i][j] = r.Next(0,9);
                        Console.Write(bs[i][j]+" ");
                    }
                    Console.WriteLine();
 
                }
 
                 //Очистка;
                for (int i = 0; i < m; i++)
                {
                  Marshal.FreeHGlobal((IntPtr)(*(a+i)));
                }
 
                Marshal.FreeHGlobal((IntPtr)bs);
                Marshal.FreeHGlobal((IntPtr)a1);
 
            }
        }
    }
0
Zodt
30.05.2018, 13:34
  #11

Не по теме:

netBool,

Цитата Сообщение от netBool Посмотреть сообщение
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
unsafe
{
     int* a = (int*)Marshal.AllocHGlobal(4);
     int* a1 = (int*)Marshal.AllocHGlobal(3);
     int* a2 = (int*)Marshal.AllocHGlobal(3);
     *a = (int)a1;
     *(a+1) = (int)a2;
     int** b = (int**)a;
     b[1][1] = 5;
     Console.WriteLine(b[1][1]);
     Marshal.FreeHGlobal((IntPtr)a);
     Marshal.FreeHGlobal((IntPtr)a1);
     Marshal.FreeHGlobal((IntPtr)a2);
}
Прям так и хочется выкрикнуть "Да здравствует С++" =)

0
0 / 0 / 0
Регистрация: 18.10.2013
Сообщений: 6
15.06.2021, 10:55 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
            unsafe
            {
                Int32 nRow = 10;
                Int32 nCol = 16;
                IntPtr tablePtr = Marshal.AllocHGlobal(nRow * sizeof(IntPtr));
                Byte** table = (byte**)tablePtr.ToPointer();
                for (Int32 i = 0; i < nRow; i++)
                {
                    table[i] = (byte*)Marshal.AllocHGlobal(nCol * sizeof(Byte));
                }
 
                for (Int32 i = 0; i < nRow; i++)
                {
                    for (Int32 j = 0; j < nCol; j++)
                    {
                        table[i][j] = Convert.ToByte(i * j);
                    }
                }
 
                for (Int32 i = 0; i < nRow; i++)
                {
                    Marshal.FreeHGlobal(new IntPtr(table[i]));
                }
                Marshal.FreeHGlobal(tablePtr);
            }
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.06.2021, 10:55

Как сделать двумерный динамический массив типа А
В общем вот пример Ну я думаю что все понятно. Что-то вроде new A Но это естественно не...

Как добавить элемент в двумерный динамический массив?
Уважаемые программисты, очень прошу помочь... Есть динамический массив, описанный как: ...

Двумерный динамический массив: как увеличить количество элементов
Доброй ночи. Возникла проблема создания двумерного массива. По сути я создал массив, но теперь его...

Как создать динамический массив?
Динамический массив создаётся подобно тому,как в Си или нет? Пример можно?


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.