Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.77/13: Рейтинг темы: голосов - 13, средняя оценка - 4.77
4 / 5 / 0
Регистрация: 14.06.2020
Сообщений: 99

Указатель на массив указателей и динамическая память

15.03.2021, 23:45. Показов 2710. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Кратко суть:
Есть структура <OBJECT> и есть необходимость хранить некоторое количество экземпляров этой структуры где-то в памяти так, чтобы была возможность обратиться к их полям и удалить в случае необходимости.
Для решения этой необходимости я создал структуру <PACK> экземпляры которой можно сформировать в очередь, получая таким образом хранилище эклемпляров структуры типа <OBJECT> нефиксированного размера.
Для хранения экземпляров типа <OBJECT> в структуре <PACK> я используй массив указателей типа <OBJECT**> память под который выделяется динамически.
Изначально каждый экземпляр типа <OBJECT> создается вне структуры <PACK> и лишь потом вносится в хранилище по средствам соотв метода.

В коде это выглядит так:
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
//  - - - - - - - - - - - - - - - - -
struct OBJECT
{
   // Данные
   // Данные
};
//  - - - - - - - - - - - - - - - - -
struct PACK
{
   OBJECT **Array;
 
   void PACK::Init(void);
   void PACK::Add(OBJECT **obj);
   void PACK::Remove(OBJECT **obj);
};
//  - - - - - - - - - - - - - - - - -
void PACK::Init(void)
{
   Array = (OBJECT**)malloc( sizeof(OBJECT*) * <количество элементов массива> );
};
//  - - - - - - - - - - - - - - - - -
void PACK::Add(OBJECT **obj)
{
   // Ищется свободный элемент <i> массива <Array> и в него копируется АДРЕС экземпляра структуры <OBJECT>
   
   Array[i] = (*obj);
};
//  - - - - - - - - - - - - - - - - -
void PACK::Remove(OBJECT **obj)
{
   // Ищется индекс <i> расположения указателя на экземпляр <OBJECT>
 
   if(Array[i] == (*obj)
   {
       free(Array[i]);
       Array[i] = NULL;
   } 
};
//  - - - - - - - - - - - - - - - - -
По итогу, при тестовых запусках программы память выделяется в полной мере, но не освобождается полность. Дебагом выяснил, что проблема в непонимании указателей на указатели в целом и в указателе на массив указателей в частности. Где ошибка?

Небыло нужды раньше использовать указатели на указатели и вот что-то не могу устаканить их в голове. От того только теряю время впустую.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.03.2021, 23:45
Ответы с готовыми решениями:

Динамическая память, указатель и непонятки
Кодом о сабже: // Просто структура struct OBJECT_A { // Any data }; // Функциональное содержание функции void...

Дан массив указателей на кольца,элементов в этом массиве не более 50,последний элемент-указатель null.Элементами кольца являются указатель на
Дан массив указателей на кольца,элементов в этом массиве не более 50,последний элемент-указатель null.Элементами кольца являются указатель...

Дан массив указателей на кольца,элементов в этом массиве не более 50,последний элемент-указатель null.Элементами кольца являются указатель на
Дан массив указателей на кольца,элементов в этом массиве не более 50,последний элемент-указатель null.Элементами кольца являются указатель...

12
11 / 10 / 1
Регистрация: 16.09.2016
Сообщений: 87
26.03.2021, 09:14
А почему вы не используете TList класс - предназначенный для хранения и управления списком указателей? По моему самое то.
0
Модератор
 Аватар для D1973
9921 / 6457 / 2457
Регистрация: 21.01.2014
Сообщений: 27,405
Записей в блоге: 3
26.03.2021, 09:37
А чем вектор не угодил?
0
фрилансер
 Аватар для Алексей1153
6461 / 5667 / 1130
Регистрация: 11.10.2019
Сообщений: 15,083
26.03.2021, 10:19
Hexpitlel,
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
#include<vector>
 
struct OBJECT
{
   int iii{1};
   double ddd{1.1};
};
 
struct PACK
{
    std::vector<OBJECT> Array;
 
    void Add(const OBJECT& obj)
    {
        Array.emplace_back(obj);
    }
    
    void Remove(const OBJECT* obj)
    {
        for(auto it=Array.begin(); it!=Array.end(); /*it++*/)
        {
            if(&*it==obj)
            {
                Array.erase(it);
                return;
            }
        }
    }
};
 
int main()
{
    PACK p;
    p.Add(OBJECT{7,7.7});
}
правда, довольно сомнительное решение насчёт Remove. Лучше по какому-нибудь id искать, а не по указателю
0
4 / 5 / 0
Регистрация: 14.06.2020
Сообщений: 99
29.03.2021, 19:59  [ТС]
Спасибо за ваши ответы. Не использую разнообразные готовые решения т.к. могу сделать более легкий и узкоспециализированный аналог.
Пока остановисля на таком решении, которое использовал когда-то ранее:
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
//  - - - - - - - - - - - - - - - - -
struct OBJECT
{
   // Данные
   // Данные
};
//  - - - - - - - - - - - - - - - - -
struct PACK
{
   unsigned int *Array;
 
   void PACK::Init(void);
   void PACK::Add(unsigned int iobj);
   void PACK::Remove(unsigned int iobj);
};
//  - - - - - - - - - - - - - - - - -
void PACK::Init(void)
{
   Array = (unsigned int*)malloc(sizeof(unsigned int*) * <количество элементов массива> );
};
//  - - - - - - - - - - - - - - - - -
void PACK::Add(unsigned int iobj)
{
   // Ищется свободный элемент <i> массива <Array> и в него копируется АДРЕС экземпляра структуры <OBJECT>
   
   Array[i] = obj;
};
//  - - - - - - - - - - - - - - - - -
void PACK::Remove(unsigned int iobj)
{
   // Ищется индекс <i> расположения указателя на экземпляр <OBJECT>
 
   if(Array[i] == obj)
   {
       free((BOT*)Array[i]);
       Array[i] = 0;
   } 
};
//  - - - - - - - - - - - - - - - - -
 
PACK       pack;
OBJECT   obj;
 
pack.Add((unsigned int)&obj);
pack.Remove((unsigned int)&obj);
0
фрилансер
 Аватар для Алексей1153
6461 / 5667 / 1130
Регистрация: 11.10.2019
Сообщений: 15,083
30.03.2021, 07:39
Цитата Сообщение от Hexpitlel Посмотреть сообщение
Не использую разнообразные встроенные возможности языка
Зачем тогда вообще C++, пиши на Си

А как будет тем, кому вдруг придётся поддерживать такие велосипеды?

Добавлено через 1 минуту
кроме того, malloc и free не вызывают конструкторы и деструкторы

Добавлено через 4 минуты
Цитата Сообщение от Hexpitlel Посмотреть сообщение
unsigned int *Array;
Цитата Сообщение от Hexpitlel Посмотреть сообщение
Array = (unsigned int*)malloc(sizeof(unsigned int*) * <количество элементов массива> );
создаёшь массив указателей, а у Array тип - указатель, это точно так нужно? о_О


Цитата Сообщение от Hexpitlel Посмотреть сообщение
unsigned int *Array;
Цитата Сообщение от Hexpitlel Посмотреть сообщение
(BOT*)Array[i]
это как это - тип unsigned int приводится к типу указатель на BOT ?
0
4 / 5 / 0
Регистрация: 14.06.2020
Сообщений: 99
30.03.2021, 11:21  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
А как будет тем, кому вдруг придётся поддерживать такие велосипеды?
Никому кроме меня. Это моя любительская поделка.
Цитата Сообщение от Алексей1153 Посмотреть сообщение
кроме того, malloc и free не вызывают конструкторы и деструкторы
Если можно обойтись без классов - всегда пишу без них.
Цитата Сообщение от Алексей1153 Посмотреть сообщение
создаёшь массив указателей, а у Array тип - указатель, это точно так нужно? о_О
Да, именно так и задумано. Ничто не мешает пошариться по выделенному куску памяти, как по массиву. А с помощью явного привидения типов, можно и поделать чего еще.
Цитата Сообщение от Алексей1153 Посмотреть сообщение
это как это - тип unsigned int приводится к типу указатель на BOT ?
Угу. Только, исходя из примера, тип <unsigned int> должен приводиться к типу <OBJECT*>. Это я допустил небольшую описку.
0
фрилансер
 Аватар для Алексей1153
6461 / 5667 / 1130
Регистрация: 11.10.2019
Сообщений: 15,083
30.03.2021, 14:00
Цитата Сообщение от Hexpitlel Посмотреть сообщение
Никому кроме меня. Это моя любительская поделка.
Цитата Сообщение от Hexpitlel Посмотреть сообщение
А с помощью явного привидения типов, можно и поделать чего еще.
но ведь всё это невозможно будет применить на реальной работе, то есть всё это останется на уровне никому не нужного хобби, не приносящего пользы никому. Стоит ли оно того?

Цитата Сообщение от Hexpitlel Посмотреть сообщение
Если можно обойтись без классов - всегда пишу без них.
да, а это что тогда?
Цитата Сообщение от Hexpitlel Посмотреть сообщение
struct PACK
0
4 / 5 / 0
Регистрация: 14.06.2020
Сообщений: 99
30.03.2021, 14:42  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
но ведь всё это невозможно будет применить на реальной работе, то есть всё это останется на уровне никому не нужного хобби, не приносящего пользы никому. Стоит ли оно того?
Я бы не был столь категоричен. Польза бывает разной.
Цитата Сообщение от Алексей1153 Посмотреть сообщение
да, а это что тогда?
<struct PACK> - объявление структуры, а <class PACK> - объявление класса. Хотя в С++ эта граница почти стерта, но структуры менее проблемные для меня.
0
фрилансер
 Аватар для Алексей1153
6461 / 5667 / 1130
Регистрация: 11.10.2019
Сообщений: 15,083
30.03.2021, 15:03
Hexpitlel, ну так в C++ структура и класс - это одно и то же. Конструкторы и деструкторы имеются и у структуры

я и говорю - с таким подходом проще на Си, там этому применение найдётся. А C++ будет больно пинать за такие вольности

Добавлено через 4 минуты
и по поводу
Цитата Сообщение от Hexpitlel Посмотреть сообщение
(BOT*)Array[i]
вот наглядный эксперимент

C++
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
 
struct OBJECT
{
};
 
int main()
{
    std::cout<<"sizeof(unsigned int)="<<sizeof(unsigned int)<<'\n';
    std::cout<<"sizeof(OBJECT*     )="<<sizeof(OBJECT*     )<<'\n';
}
sizeof(unsigned int)=4
sizeof(OBJECT* )=8


https://onlinegdb.com/U9TqxNj79
0
4 / 5 / 0
Регистрация: 14.06.2020
Сообщений: 99
30.03.2021, 15:50  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
ну так в C++ структура и класс - это одно и то же. Конструкторы и деструкторы имеются и у структуры
Отвечу вам подругому. Если для решения задачи достаточно комплексных данных (структур, без наследования, полиморфизма и инкапсуляции) то к классам я прикасаться не буду никаким боком.
Для этой задачи необходим только комплексные данные и больше ничего. Нет потребности в классах.

Вы упускаете разницу между этим
C++
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
 
struct OBJECT
{
};
 
int main()
{
    std::cout<<"sizeof(unsigned int)="<<sizeof(unsigned int)<<'\n';
    std::cout<<"sizeof(OBJECT*     )="<<sizeof(OBJECT*     )<<'\n';
}
и этим

C++
1
2
Array = (unsigned int*)malloc(sizeof(unsigned int*) * <количество элементов массива> );
(OBJECT*)Array[i];
Я вообще могбы записать выражение любым из следующих вариантов и ничего бы не изменилось от слова совсем
C++
1
2
3
Array = (unsigned int*)malloc(sizeof(int*) * <количество элементов массива> );
Array = (unsigned int*)malloc(sizeof(OBJECT*) * <количество элементов массива> );
Array = (unsigned int*)malloc(sizeof(bool*) * <количество элементов массива> );
Без разницы указателей какого типа будет массив <Array> - с помощью явного приведения типов (указателей в данном примере) это несущественно.
0
фрилансер
 Аватар для Алексей1153
6461 / 5667 / 1130
Регистрация: 11.10.2019
Сообщений: 15,083
30.03.2021, 16:13
Цитата Сообщение от Hexpitlel Посмотреть сообщение
то к классам я прикасаться не буду никаким боком.
так уже прикоснулся же
Цитата Сообщение от Hexpitlel Посмотреть сообщение
struct OBJECT
Цитата Сообщение от Hexpitlel Посмотреть сообщение
struct PACK

Цитата Сообщение от Hexpitlel Посмотреть сообщение
Вы упускаете разницу между этим
я ничего не упускаю:

Цитата Сообщение от Hexpitlel Посмотреть сообщение
struct PACK
{
   unsigned int *Array;
Цитата Сообщение от Hexpitlel Посмотреть сообщение
(OBJECT*)Array[i];
объект unsigned int размером 4 байта насильно преобразуется к объекту OBJECT* размером в восемь байтов. Просто супер!

даже компилятор пишет предупреждение:
warning: cast to pointer from integer of different size
C++
1
2
    unsigned int Array[1]{};
    OBJECT* p=(OBJECT*)Array[0];
Добавлено через 2 минуты
Hexpitlel, не подумай, что я пытаюсь тут критику какую-то навести. Просто предупреждаю, что это всё не будет работать в C++, пиши лучше на Си. Там нет конструкторов, деструкторов. Однако размеры объектов всё равно придётся учитывать
0
4 / 5 / 0
Регистрация: 14.06.2020
Сообщений: 99
30.03.2021, 16:25  [ТС]
Это 32-битное приложение.

Добавлено через 2 минуты
Я эту тему размещал в разделе "C++ Builder". Без понятия, кто и куда ее перенес.

Добавлено через 1 минуту
А так да, вы правильно сделали замечание.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
30.03.2021, 16:25
Помогаю со студенческими работами здесь

Дан массив указателей на кольца,элементов в этом массиве не более 50,последний элемент-указатель null.Элементами кольца являются указатель на
Дан массив указателей на кольца,элементов в этом массиве не более 50,последний элемент-указатель null.Элементами кольца являются указатель...

указатель на массив указателей
помогите разобраться, передаю в функцию update_table массив указателей на фигуры, для каждой из которых должна вызываться add_to_table....

Указатель на массив указателей
Доброго времени суток. Имеется класс Kino, содержащий в себе некоторые поля данных и методы к ним. Другой же класс, класс KinoMassiv,...

Массив указателей на указатель
Помогите, пожалуйста. У нас есть объявление int **m6; Нужно представить и нарисовать, как данный массив 10 указателей на указатель,...

Вернуть указатель на массив указателей
Всем привет! Написал маленький код: int WHAT(); int main() { cout&lt;&lt;WHAT();


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru