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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
darkAngel
Технофашист
216 / 199 / 4
Регистрация: 11.03.2009
Сообщений: 883
#1

Динамический массив указателей - C++

04.09.2010, 08:34. Просмотров 27864. Ответов 28
Метки нет (Все метки)

Чегото не пойму такое вообще возможно?
Странно, что при объявлении можно не указывать размерность: int *a[];
Но как потом память выделять не известно.

Добавлено через 2 минуты
p.s. прошу не путать с указателем на массив.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.09.2010, 08:34
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Динамический массив указателей (C++):

Динамический массив указателей - C++
есть вот такой массив. void* pppribarray = { NULL, NULL, NULL, NULL }; каждый его элемент это указатель на разные пользовательские типы...

Динамический массив указателей - C++
Есть класс "блока" - MapBuilderClass::BlockClass. Надо создать массив из MapBuilderClass::BlockClass* (из указателей на "блок"), изменять...

Динамический массив указателей - C++
Нужен массив указателей на тип родительского класса Game, как его правильно оформить? То что я написал выдает ошибку. #include...

Динамический массив указателей на структуру - C++
Не могу понять как выделить место под динамический массив указателей на структуру с помощью new. Все верно делаю? int lol = 1024; ...

Динамический массив с использованием указателей - C++
Дан двумерный массив целых чисел размером , где m и n – заданные натуральные числа. Если в массиве есть такие две строки, что все элементы...

Динамический массив указателей на объекты - C++
вообщем была тут на форуме задача, в подробности вдаваться не буду, смысл сейчас заключается в том, чтобы создавать в цикле объекты, и в их...

28
Nick Alte
Эксперт С++
1639 / 1011 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
04.09.2010, 15:19 #2
Память обычно выделяется инициализацией:
C
1
2
int a, b, c;
int* array[] = {&a, &b, &c};
0
Day
1158 / 963 / 57
Регистрация: 29.10.2009
Сообщений: 1,385
05.09.2010, 22:26 #3
darkAngel, объявление int *a[]; эквивалентно int **a;
А память выделяется так:
C
1
2
3
  a = malloc(10*sizeof(int *));
  for(i=0; i<10; i++)
    a[i] = malloc((5+i)*sizeof(int));
Получится такая "косая" матрица
1-я строка - 5 элементов
2-я - 6
...
10-я - 14
А можно и по-другому, скажем чтоб все строки были одинаковы...
Это уж твое дело, управляешь этим ТЫ
0
easybudda
Модератор
Эксперт CЭксперт С++
9664 / 5614 / 952
Регистрация: 25.07.2009
Сообщений: 10,781
05.09.2010, 22:37 #4
Цитата Сообщение от Day Посмотреть сообщение
darkAngel, объявление int *a[]; эквивалентно int **a;
Ничего подобного! Выражение int **a; обявляет указатель на указатель на int; а int *a[]; объявляет массив указателей, но в таком виде оно не правильно, и так даже не скомпилируется. Если при объявлении массива не указывается размер, вместе с объявлением должна быть инициализация значений, тогда компилятор вычисляет размер автоматически:
C
1
2
3
int **a; // при объявлении инициализация не требуется
int *b[] = { NULL, NULL, NULL }; // создаёт массив из трёх указателей, инициализирует их значением NULL
int *c[]; // выдаст ошибку при компиляции
2
Day
1158 / 963 / 57
Регистрация: 29.10.2009
Сообщений: 1,385
05.09.2010, 22:44 #5
easybudda, Приношу извинения. Ты прав.
0
darkAngel
Технофашист
216 / 199 / 4
Регистрация: 11.03.2009
Сообщений: 883
06.09.2010, 08:13  [ТС] #6
int *b[] = { NULL, NULL, NULL };
Размер массива мне не известен заранее.
Массив указателей - это поле моего класса, на сколько объектов он будет ссылаться - будет известно лишь в процессе инициализации.
0
easybudda
Модератор
Эксперт CЭксперт С++
9664 / 5614 / 952
Регистрация: 25.07.2009
Сообщений: 10,781
06.09.2010, 09:05 #7
Цитата Сообщение от darkAngel Посмотреть сообщение
Массив указателей - это поле моего класса, на сколько объектов он будет ссылаться - будет известно лишь в процессе инициализации.
На форуме полно примеров!

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
...
int **matrix, rows, columns;
/* инициализировать rows и columns */
matrix = new int* [ rows ];
for ( int i = 0; i < rows; ++i )
  matrix[i] = new int [ columns ];
...
for ( int i = 0; i < rows; ++i ){
  for ( int j = 0; j < columns; ++j ){
    /* что-то сделать с matrix[i][j] */
  }
}
...
for ( int i = 0; i < rows; ++i )
  delete [] matrix[i];
delete [] matrix;
...
C - стиль, с классами не использовать!
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
#include <stdlib.h>
#include <stdio.h>
...
int ** matrix, rows, columns, i, j;
/* инициализировать rows и columns */
if ( ( matrix = (int**)malloc(sizeof(int*) * rows) ) == NULL ){
  perror("malloc");
  exit(1);
}
for ( i = 0; i < rows; ++i ){
  if ( ( matrix[i] = (int*)malloc(sizeof(int) * columns) ) == NULL ){
    perror("malloc");
    exit(1);
  }
}
...
for ( i = 0; i < rows; ++i ){
  for ( j = 0; j < columns; ++j ){
    /* что-то сделать с matrix[i][j] */
  }
}
...
for ( i = 0; i < rows; ++i )
  free(matrix[i]);
free(matrix);
...
1
darkAngel
Технофашист
216 / 199 / 4
Регистрация: 11.03.2009
Сообщений: 883
06.09.2010, 10:09  [ТС] #8
easybudda, арррр... попросил же не путать с указателем на массив.

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

Добавлено через 7 минут
p.s. вот, в кратце:
C++
1
2
3
4
5
6
7
8
9
10
11
12
struct top{   //Такой тип
...
};
top *N[50];   //Нужен такой массив указателей, только количество элементов мне не известно при компиляции
top *A;        //Указатель на массив, где последовательно хранятся элементы типа top
...
/*выделяем память под массив типа top, на начало которого ссылается указатель A*/
...
/*Теперь мне выборочно нужно ссылатся на некоторые элементы из множества A*/
N[0] = &A[3];
N[1] = &A[17];
N[2] = &A[22];
И повторяю, проблема в том, что не известна размерность массива N до компиляции
0
easybudda
Модератор
Эксперт CЭксперт С++
9664 / 5614 / 952
Регистрация: 25.07.2009
Сообщений: 10,781
06.09.2010, 10:42 #9
Цитата Сообщение от darkAngel Посмотреть сообщение
И повторяю, проблема в том, что не известна размерность массива N до компиляции
Ну и в чём проблема?
C++
1
2
3
4
5
6
7
8
9
10
11
12
...
struct Top{
...
};
int tops_needed;
...
Top * tops = new Top [ tops_needed ];
for ( int i = 0; i < tops_needed; ++i )
  tops[i] = another_top_object;
...
delete [] tops;
...
0
darkAngel
Технофашист
216 / 199 / 4
Регистрация: 11.03.2009
Сообщений: 883
06.09.2010, 10:52  [ТС] #10
В том что выделяется память и создаётся копия, а мне нужна не копия данных, а указатель на уже выделенную память.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct Top{
int d;
...
};
int tops_needed;
...
Top A;                             //Создали объект A типа Top и инициализировали поле d
A.d = 5;              
 
Top * tops = new Top [ tops_needed ];
for ( int i = 0; i < tops_needed; ++i )
  [B]tops[i] = A;[/B]                            //Создали копию объекта A
 
A.d = 7;                    //Изменили значение поля d
Выводим данные:
A.d равно 7
tops[0].d равно 5
ибо копия
0
easybudda
Модератор
Эксперт CЭксперт С++
9664 / 5614 / 952
Регистрация: 25.07.2009
Сообщений: 10,781
06.09.2010, 11:33 #11
Цитата Сообщение от darkAngel Посмотреть сообщение
выделяется память и создаётся копия, а мне нужна не копия данных, а указатель на уже выделенную память.
C++
1
2
3
4
5
6
7
8
9
10
11
...
Top a, b, c;
int numTops = 3;
Top ** pTops = new Top * [ numTops ];
pTops[0] = &a;
pTops[1] = &b;
pTops[2] = &c;
for ( int i = 0; i < numTops; ++i )
  std::cout << pTops[i]->d;
...
delete [] pTops;
0
for.joke
Сообщений: n/a
25.12.2010, 14:08 #12
Цитата Сообщение от easybudda Посмотреть сообщение
Ничего подобного! Выражение int **a; обявляет указатель на указатель на int; а int *a[]; объявляет массив указателей, но в таком виде оно не правильно, и так даже не скомпилируется.
С помощью выражения int **a; можно спокойно создать динамический массив указателей)

Добавлено через 22 минуты
Вот допустим динамический массив указателей на объекты класса, с конструктором:
C++
1
2
3
4
5
6
ex::ex(char* s, int n)
{
    str=new char[strlen(s)+1];
    strcpy(str,s);
    num=n;
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void main()
{
    int nm,n;
        cin>>n;
 
    ex **spisok= new ex*[n];
    char **temp=new char*[n];
    for(int i=0;i<n;i++)
        temp[i]=new char[50];
    
    for(int i=0;i<n;i++)
    {
        cin>>temp[i];
        cin>>nm;
        spisok[i]= new ex(temp[i], nm);
        cout<<spisok[i]->getstr()<<"\t"<<spisok[i]->getint()<<"\n";
    }
 
}
Izual
94 / 119 / 6
Регистрация: 13.11.2012
Сообщений: 1,552
27.12.2016, 18:56 #13
Не хотел создавать новую тему.. а т.к. вопрос к месту, то думаю можно и тут:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void **ppv;
unsigned long long MXsize = 10;
int *pi=NULL, mi[]={7,10,5,3};
pi = mi;
 
ppv = new(nothrow) void* [MXsize]; // создали 10 указателей на указатели
if(ppv == NULL)
    return -3;
for(int i=0;i<MXsize;i++){ppv[i]=NULL;}
cout << "**ppv adress: " << &ppv << endl;
for(int i=0;i<MXsize;i++){cout << "**ppv[" << i << "] adress: " << &ppv[i];
if(ppv[i]==NULL) cout << ". No data" << endl;
else cout << ". data: " << ppv[i] << endl;}
ppv[0]=pi;
if(ppv[0]!=NULL) cout << "pInt-M[0] adress: " << ppv[0] << " and ppv[0] adress: " << &ppv[0] << " and data: " << *(int*)ppv[0] << endl;
else cout << "ppv[0] adress: " << &ppv[0] << " and it is NULL" << endl;
delete [] ppv;
Меня интересует, почему я не могу обратиться вместо этого: *(int*)ppv[0] как обычно вот так: ppv[0][0]
Компиллер MSVC выдаёт ошибку..
0
darkAngel
Технофашист
216 / 199 / 4
Регистрация: 11.03.2009
Сообщений: 883
27.12.2016, 19:16  [ТС] #14
Цитата Сообщение от Izual Посмотреть сообщение
Меня интересует, почему я не могу обратиться вместо этого: *(int*)ppv[0] как обычно вот так: ppv[0][0]
потомучто у вас указатель типа void, а не int.

Добавлено через 3 минуты
Компилятору нужно знать информацию о типе (нужно знать смещение в байтах), когда вы пытаетесь обратиться к элементу массива. Первый ваш вариант (правильный) как раз и предоставляет такую информацию компилятору.

Добавлено через 4 минуты
И кстати в таком виде *(int*)ppv[0] вы указывате доступ только к первому элементу массива. Более точнее можно сделать так: ((int**)ppv)[i][j]

Сперва вы указываете, чтобы ваш массив ppv типа void** читался компилятором как тип int**, далее вы уже работаете с этим массивом как с массивом int и можете осуществлять обычный доступ через [i][j]

Добавлено через 4 минуты
Так, и кажется у вас там ошибки. Если вы хотите, чтобы ваш массив void хранил данные типа int, то вы должны явно выделять память для int, а не для void пеерменных (строка ppv = new(nothrow) void* [MXsize] и когда присваиваете значения к этому массиву, вы также должны делать явное приведение к тому типу, который присваиваете.

Вообще, зачем вам понадобился void, если вы явно потом используете int? Void обычно используется, если не известно заранее, на какой типа данных он будет указывать.
1
Izual
94 / 119 / 6
Регистрация: 13.11.2012
Сообщений: 1,552
27.12.2016, 19:28 #15
Цитата Сообщение от darkAngel Посмотреть сообщение
((int**)ppv)[i][j]
Спасибки.

Цитата Сообщение от darkAngel Посмотреть сообщение
Компилятору нужно знать информацию о типе
Ну это понятно, что кастить надо, просто оно ни как не работало, вот и не стал писать.
Цитата Сообщение от darkAngel Посмотреть сообщение
Если вы хотите, чтобы ваш массив void хранил данные типа int, то вы должны явно выделять память для int, а не для void пеерменных
Не переменные, а указатели! А вот "указатели указателей" буду кастить.
По факту указатель любого типа - 4 байтный (в 32 битной ОС), так что выделяя память под указатели - чисто по логике вообще фиолетово что написать void или int, да что угодно..

Цитата Сообщение от darkAngel Посмотреть сообщение
зачем вам понадобился void, если вы явно потом используете int? Void обычно используется, если не известно заранее, на какой типа данных он будет указывать.
Потому что это лишь пример.. на самом деле всё будет "не известно", и под каждый тип будет свой каст.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.12.2016, 19:28
Привет! Вот еще темы с ответами:

Создать динамический массив указателей - C++
Создать динамический массив указателей для сохранения двумерного массива А в динамической памяти. Составить программу для подсчета...

Создайте динамический массив указателей на структуры - C++
Задача: дана структура struct Sample { char c; double x; int *p; }; Создайте динамический массив указателей на...

Динамический массив указателей на объекты класса - C++
Добрый вечер! Нужна помощь У меня имеется класс STROKA(вроде уже готовый,и все хорошо) Только вот никак не могу понять, как создать...

Как сделать динамический массив из указателей? - C++
Всем привет! Как сделать динамический массив я знаю,и как сделать массив из указателей я знаю,а как сделать динамический массив из...


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

Или воспользуйтесь поиском по форуму:
15
Yandex
Объявления
27.12.2016, 19:28
Ответ Создать тему
Опции темы

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