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

Переопределение размера массива указателей - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.64
CheburatorUA
0 / 0 / 0
Регистрация: 27.03.2014
Сообщений: 24
11.08.2014, 15:05     Переопределение размера массива указателей #1
Доброе время суток. Столкнулся с неожиданно проблемой, не могу решить. Поиск по форуму ничего не дал.
Есть элементарный код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
using namespace std;
 
void main()
{
    int i=0;
    const int n = 3;
    int *b[n];
    while(i<n)
    {
        b[i] = new int;
        i++;
    }
    i=0;
    *b[0] = 1;
    *b[1] = 2;
    *b[2] = 3;
    while (i<n)
        {
            cout<<*b[i]<<endl;
            i++;
        }
}
Т.е ничего сложного - выделяем массив указателей затем по ним выделяем память, записываем в неё значение и выводим его на экран. Так вот вопрос: возможно ли размер этого массива определять вручную с консоли или как-то его задать на основе предварительных расчетов? Не константное значение компилятор не принимает. Такой вот код int a = 2+1; const int n = a; int *b[n]; не принимает говорит, что n не константа. Такой тоже int a = 2+1; int *b[a] не компилирует; Как я не кручу не получается т.е. или надо писать *b[3] или const int n = 3; int *b[n]; А мне нужно в процессе выполнения программы задать размер на основе предшествующего расчета.
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
John Prick
754 / 687 / 123
Регистрация: 27.07.2012
Сообщений: 1,974
Завершенные тесты: 3
11.08.2014, 15:22     Переопределение размера массива указателей #2
C++
1
2
std::cin >> n; // например
int ** b = new int*[n];
CheburatorUA
0 / 0 / 0
Регистрация: 27.03.2014
Сообщений: 24
11.08.2014, 15:40  [ТС]     Переопределение размера массива указателей #3
Но ведь b здесь это указатель на массивы указателей. А у меня b - массив указателей на данные типа int.
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
11.08.2014, 16:03     Переопределение размера массива указателей #4
CheburatorUA, в Вашем случае смысла в динамическом выделении памяти нет (строка 11). Когда требуется выделить память по запросу пользователя обычно делают почти так как указал John Prick, только выделять память всё таки нужно под данные, а не под указатели.
C++
1
2
3
std::cin >> n; 
int* b = new int[n]; // выделяем память для n целых
// потом можно использовать b[0] ... b[n-1] для доступа к данным
P.S. Поищите темы на форуме с названиями типа "динамическое создание матрицы" чтобы прояснить ситуацию.
CheburatorUA
0 / 0 / 0
Регистрация: 27.03.2014
Сообщений: 24
11.08.2014, 16:06  [ТС]     Переопределение размера массива указателей #5
Я сделал так как вы написали
C++
1
2
3
4
5
int n =3;
int ** c = new int*[n];
    *c[0] = 1;
    *c[1] = 2;
    *c[2] = 3;
Не работает.

C++
1
2
3
4
5
int n =3;
int ** c = new int*[n];
    c[0] = 1;
    c[1] = 2;
    c[2] = 3;
так тоже не работает.

И мне не нужна матрица или двумерный динамический массив. В матрице мы создаем массив указателей на массив указателей. А мне просто нужен массив указателей.
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6173 / 2902 / 284
Регистрация: 04.12.2011
Сообщений: 7,725
Записей в блоге: 3
11.08.2014, 16:06     Переопределение размера массива указателей #6
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от CheburatorUA Посмотреть сообщение
Но ведь b здесь это указатель на массивы указателей
Это указатель на указатель. Может указывать на один указатель, а может и на начало аж целого массива указателей.
Когда Вы пишете объявление автоматического массива:
int a[n];
или
int *b[n];
Вы просите компилятор выделить память в области объявления на стадии компиляции и значит n должен быть вычисляем на стадии компиляции (быть константным выражением). John Prick показал Вам, что выделение динамической памяти под тип или под указатель на тип, в принципе одинаковы. То есть, если нужно выделить память с размером времени выполнения, это единственный путь: new/malloc.
Цитата Сообщение от Tulosba Посмотреть сообщение
в Вашем случае смысла в динамическом выделении памяти нет
Я думаю (экстрасенсорика) ТС знает как выделить под массив целых, но экспериментирует на предмет создания массива с динамически изменяемым размером. Отсюда и попытки навыделять под указатели, а потом...
CheburatorUA, тут грибов нет. Смотрите std::vector.
SatanaXIII
Супер-модератор
Эксперт С++
 Аватар для SatanaXIII
5549 / 2563 / 233
Регистрация: 01.11.2011
Сообщений: 6,337
Завершенные тесты: 1
11.08.2014, 16:18     Переопределение размера массива указателей #7
Может быть вот так вот будет нагляднее:
C++
1
2
3
int n = 3;
typedef int* pInt;
pInt *b = new pInt[n];
CheburatorUA
0 / 0 / 0
Регистрация: 27.03.2014
Сообщений: 24
11.08.2014, 23:20  [ТС]     Переопределение размера массива указателей #8
IGPIGP, Да, вектором получилось, спасибо. Буквально самое начало про него прочитал и уже вкумекал как сделать. Вот как-то так:
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
#include <iostream>
using namespace std;
#include "vector"
 
void main()
{
    int a= 2;
    int i = 0;
    int n = a+1;
    vector<int*>b(n);
    while(i<n)
    {
        b[i] = new int;
        i++;
    }
    *b[0] = 1;
    *b[1] = 2;
    *b[2] = 3;
    i=0;
    while (i<n)
        {
            cout<<*b[i]<<endl;
            i++;
        }
    cout<<endl;
 
}
Ещё раз спасибо за наводку.
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6173 / 2902 / 284
Регистрация: 04.12.2011
Сообщений: 7,725
Записей в блоге: 3
12.08.2014, 00:39     Переопределение размера массива указателей #9
Цитата Сообщение от CheburatorUA Посмотреть сообщение
#include "vector"
Так тоже находит.
Не забудьте освободить память если нужно.
WinRar007
 Аватар для WinRar007
1 / 1 / 0
Регистрация: 08.04.2014
Сообщений: 80
20.08.2014, 21:58     Переопределение размера массива указателей #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
template <class TypeName>
class DinamicMassive
{
public:
    TypeName **Massive;
    int N;
    bool Seted = false;
    DinamicMassive()
    {
        N = 1;
        Massive = new TypeName*[N];
    }
    ~DinamicMassive()
    {
        delete Massive;
    }
    void ChangeLenght(int NewLenght)
    {
        TypeName **Massive2 = new TypeName*[NewLenght];
        int i2 = 0;
        for (int i = 0; i < N; i++)
        {
            if (Massive[i + i2] != 0)
            {
                Massive2[i] = Massive[i + i2];
            }
            else
            {
                i2++;
            }
        }
        N = NewLenght;
        delete Massive;
        Massive = Massive2;
    }
private:
};
Всё компилируется, но не смотря на указанное число элементов в массиве (Строка 11 и 19) создаётся только один элемент. Подозреваю, что запутался в указателях.
P.S. Память для самих элементов (На которые указывают указатели из нашего массива) выделяется отдельно.
John Prick
754 / 687 / 123
Регистрация: 27.07.2012
Сообщений: 1,974
Завершенные тесты: 3
20.08.2014, 22:07     Переопределение размера массива указателей #11
Цитата Сообщение от WinRar007 Посмотреть сообщение
создаётся только один элемент.
C++
1
2
        N = 1;
        Massive = new TypeName*[N];
Ну как бы да, сказано создать массив из 1го элемента.

И, кстати, надо так (повсеместно):
C++
1
delete [] Massive;
Добавлено через 1 минуту
А ещё, здесь уже звучал совет, чтобы не теряться в "звёздочках":
C++
1
2
3
4
typedef TypeName* PTypeName;
typedef PTypeName PPTypeName;
//...
PPTypeName Massive = new PTypeName[100500];
WinRar007
 Аватар для WinRar007
1 / 1 / 0
Регистрация: 08.04.2014
Сообщений: 80
20.08.2014, 22:27     Переопределение размера массива указателей #12
У меня один элемент создаётся даже если поменять N на любое другое число.
John Prick
754 / 687 / 123
Регистрация: 27.07.2012
Сообщений: 1,974
Завершенные тесты: 3
20.08.2014, 22:51     Переопределение размера массива указателей #13
Как ты определяешь, что создаётся только 1 элемент?
Alex5
883 / 618 / 81
Регистрация: 12.04.2010
Сообщений: 1,552
20.08.2014, 22:58     Переопределение размера массива указателей #14
Цитата Сообщение от WinRar007 Посмотреть сообщение
C++
1
2
3
4
5
6
7
Massive = new TypeName*[N];
 }
 ~DinamicMassive()
 {
 ////delete Massive;
  /* если  new a[N];   то необходимо    delete[] a; */
  delete[] Massive;
Если new[], то и delete[]

Цитата Сообщение от WinRar007 Посмотреть сообщение
создаётся только один элемент
WinRar007, как Вы определили, что элемент только один?
WinRar007
 Аватар для WinRar007
1 / 1 / 0
Регистрация: 08.04.2014
Сообщений: 80
20.08.2014, 23:50     Переопределение размера массива указателей #15
Как-как, через отладку!
Миниатюры
Переопределение размера массива указателей  
John Prick
754 / 687 / 123
Регистрация: 27.07.2012
Сообщений: 1,974
Завершенные тесты: 3
21.08.2014, 00:10     Переопределение размера массива указателей #16
WinRar007, а что ты хочешь увидеть в отладке? Ты, по сути, создаёшь указатель, инициализируешь его адресом первого элемента массива указателей, созданного динамически, - это всё, что видит отладчик. Он не покажет тебе весь массив, как если бы ты написал int* array[100500], потому что он знает только про указатель и ничего не знает про то, чем он был инициализирован во время выполнения программы.
WinRar007
 Аватар для WinRar007
1 / 1 / 0
Регистрация: 08.04.2014
Сообщений: 80
21.08.2014, 08:55     Переопределение размера массива указателей #17
John Prick,
Ага, понятно, спасибо. Но тогда возникают вопросы:
Во первых, как узнать количество?
Во вторых, почему при моей криворукости при любом размере массива программа корректно обращается только к нулевому элементу. Про другие ругается, что не может по такому адресу обратиться?
John Prick
754 / 687 / 123
Регистрация: 27.07.2012
Сообщений: 1,974
Завершенные тесты: 3
21.08.2014, 10:29     Переопределение размера массива указателей #18
Цитата Сообщение от WinRar007 Посмотреть сообщение
Во первых, как узнать количество?
Ну ты же задавал количество элементов в []. Вот его и надо смотреть, по другому никак. Тем более, что ты же специально создаёшь класс-обёртку. Вот там и можешь сохранить это число:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template<class TypeName>
class DinamicMassive
{
public:
    DinamicMassive()
    {
        const int N = 10;
        Massive = new TypeName*[N];
        size = N;
    }
    int Size() const { return size; }
// ...
private:
    int size;
};
Добавлено через 40 секунд
Цитата Сообщение от WinRar007 Посмотреть сообщение
Во вторых, почему при моей криворукости при любом размере массива программа корректно обращается только к нулевому элементу. Про другие ругается, что не может по такому адресу обратиться?
Нужно смотреть, как ты обращаешься к элементам этого массива.
WinRar007
 Аватар для WinRar007
1 / 1 / 0
Регистрация: 08.04.2014
Сообщений: 80
21.08.2014, 10:35     Переопределение размера массива указателей #19
Пример:
C++
1
CheckCollision(Settings.Time / loops, Bodies.Massive[i], Bodies.Massive[i2]);
C++
1
2
3
4
5
6
void CheckCollision(float T, Body *body1, Body *body2)
    {                                              
        if (body1->ColType != 0 && body2->ColType != 0 && body1 != body2)
        {
            if (!body1->Continue && !body2->Continue)
            {
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.08.2014, 10:55     Переопределение размера массива указателей
Еще ссылки по теме:

C++ Задание размера и инициализация массива указателей в конструкторе
Сортировка массива структур через сортировку массива указателей C++
C++ Связь массива и указателей

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

Или воспользуйтесь поиском по форуму:
John Prick
754 / 687 / 123
Регистрация: 27.07.2012
Сообщений: 1,974
Завершенные тесты: 3
21.08.2014, 10:55     Переопределение размера массива указателей #20
И что это за числа i и i2? И что находится в этих элементах массива?
Yandex
Объявления
21.08.2014, 10:55     Переопределение размера массива указателей
Ответ Создать тему
Опции темы

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