С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.69/16: Рейтинг темы: голосов - 16, средняя оценка - 4.69
half-horse half-gateway
117 / 83 / 43
Регистрация: 10.05.2016
Сообщений: 563

Указание определенного адреса памяти для указателя

29.10.2020, 19:56. Показов 3398. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день всем. Сидел, баловался с памятью и вдруг задумался: а можно ли указатель определять на конкретный адрес? Чтобы было понятнее, вот примерный простенький код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
using namespace std;
 
template<class Type>
struct Node
{
    Node<Type>* next = nullptr;
    Type* value = nullptr;
};
 
int main()
{
    Node<int>* list = new Node<int>();
    list->value = new int(1);
    list->next = list + 1;
    list->next->value = new int(80);
 
    cout << list << "\t" << *(list->value) << "\t" << list->next << "\t" << *(list->next->value) << endl;
 
    return 0;
}
По сути, если такой код можно считать безопасным, то следующим шагом было бы определение класса List, в котором перегружался бы оператор [], т.е. к элементам списка можно было бы обращаться по индексу:
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
template<class Type>
class List
{
public:
 
    /* <...> */
    
    Type& operator[] (const size_t index)
    {
        return *(list + index);
    }
 
    void add(const Type& element)
    {
        Node<Type>* temp = list + size - 1;
        temp->next = temp + 1;
        *(temp->next->value) = element;
        size++;
    }
 
    /* <...> */
 
private:
 
    Node<Type> list;
 
    size_t size = 0;
}
Но у меня, естественно, существует большие сомнения на счет безопасности такого кода. Но хотелось бы конкретики по этому поводу (ссылки на литературные источники очень даже приветствуются). Заранее спасибо за ответ.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
29.10.2020, 19:56
Ответы с готовыми решениями:

Динамическое указание адреса указателя
мне нужно сделать int * a=(int*)0x123ff; cout&lt;&lt;a; динамически. Кто нибудь знает как это сделать?

выделение памяти при увеличении адреса указателя на размерность int
добрый день, форум изучаю указатели и столкнулся с достаточно странной, для меня проблемой int в c++, как я учил, имеет стандартную...

Указание лимита памяти для приложения
На Unix-системах есть такая замечательная команда как -m, которая ограничивает максимальный объем виртуальной памяти, который может занять...

16
76 / 68 / 10
Регистрация: 11.07.2016
Сообщений: 320
29.10.2020, 20:08
Ты пытаешься из списка сделать массив. Зачем?
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
29.10.2020, 20:14
Лучший ответ Сообщение было отмечено BlackStoneBlack как решение

Решение

Цитата Сообщение от BlackStoneBlack Посмотреть сообщение
По сути, если такой код можно считать безопасным
менеджер кучи кто в известность поставит что ты по адресу list + 1 разместил int(80), так делать нельзя

Добавлено через 2 минуты
BlackStoneBlack, если хочешь с памятью играть по правилам, то сначала нужно большой кусок в куче выделить, потом уже как тебе угодно эту память раздавать

Добавлено через 1 минуту
Цитата Сообщение от BlackStoneBlack Посмотреть сообщение
ссылки на литературные источники очень даже приветствуются
загугленно
1
half-horse half-gateway
117 / 83 / 43
Регистрация: 10.05.2016
Сообщений: 563
29.10.2020, 20:48  [ТС]
Цитата Сообщение от Zirak Посмотреть сообщение
Ты пытаешься из списка сделать массив. Зачем?
Например, банальное ускорение работы со списком. В том же C# в типе List переопределен оператор [] и есть свойсво Count, возвращающее количество элементов. Но вообще, это просто интерес.
Цитата Сообщение от _stanislav Посмотреть сообщение
менеджер кучи кто в известность поставит что ты по адресу list + 1 разместил int(80), так делать нельзя
Вот именно поэтому у меня и были сомнения по этому поводу.
Цитата Сообщение от _stanislav Посмотреть сообщение
BlackStoneBlack, если хочешь с памятью играть по правилам, то сначала нужно большой кусок в куче выделить, потом уже как тебе угодно эту память раздавать
Да, я уже примерно стал доходить до этого.
Цитата Сообщение от _stanislav Посмотреть сообщение
загугленно
Спасибо, понял, в каком направлении копать.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12931 / 6799 / 1820
Регистрация: 18.10.2014
Сообщений: 17,211
29.10.2020, 20:55
Цитата Сообщение от BlackStoneBlack Посмотреть сообщение
Чтобы было понятнее, вот примерный простенький код:
Совершенно не стало понятнее, при чем здесь "указатель на конкретный адрес".

Цитата Сообщение от BlackStoneBlack Посмотреть сообщение
По сути, если такой код можно считать безопасным,
Нет, разумеется. В коде написана полная бессмыслица:
C++
1
2
3
4
    Node<int>* list = new Node<int>();
    list->value = new int(1);
    list->next = list + 1;
    list->next->value = new int(80);
Кто вам разрешил лезть в list + 1? Там нет памяти.
0
76 / 68 / 10
Регистрация: 11.07.2016
Сообщений: 320
29.10.2020, 21:08
Цитата Сообщение от BlackStoneBlack Посмотреть сообщение
В том же C# в типе List переопределен оператор []
Я почти на 100% уверен, что там просто нужное количество раз переходится по next. Если нужна скорость используй массив, список, особенно хоть сколь-нибудь большой, всегда будет очень медленным на его фоне. Конечно, можно завести дополнительный ассоциативный массив, где ключ это индекс, а значение - нужный указатель. Но с таким подходом уже и список не нужен.
0
half-horse half-gateway
117 / 83 / 43
Регистрация: 10.05.2016
Сообщений: 563
29.10.2020, 21:29  [ТС]
Цитата Сообщение от Zirak Посмотреть сообщение
Я почти на 100% уверен, что там просто нужное количество раз переходится по next
Возможно, я исходники там не ковырял.
Цитата Сообщение от Zirak Посмотреть сообщение
Конечно, можно завести дополнительный ассоциативный массив, где ключ это индекс, а значение - нужный указатель. Но с таким подходом уже и список не нужен.
Да, согласен. Хотя с изменением размера массива уже не все так хорошо, как хотелось бы. Хотя и существует тот же класс vector. Надо будет пошариться в его исходниках
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9005 / 4706 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
30.10.2020, 00:08
Цитата Сообщение от Zirak Посмотреть сообщение
Я почти на 100% уверен, что там просто нужное количество раз переходится по next.
https://docs.microsoft.com/en-... etcore-3.1
То есть, этот список не совсем список. Совсем не список, вернее. Это массив в динамической памяти. Если я правильно понял, о каком списке в шарпе идёт речь.

Добавлено через 5 минут
О более новом List<T> из System.Collections.Generic
https://docs.microsoft.com/en-... etcore-3.1
они пишут похожее нечто:
Цитата Сообщение от MS cave
Remarks

The List<T> class is the generic equivalent of the ArrayList class. It implements the IList<T> generic interface by using an array whose size is dynamically increased as required.
0
 Аватар для Annemesski
2670 / 1333 / 479
Регистрация: 08.11.2016
Сообщений: 3,683
30.10.2020, 11:42
Лучший ответ Сообщение было отмечено BlackStoneBlack как решение

Решение

Цитата Сообщение от BlackStoneBlack Посмотреть сообщение
Например, банальное ускорение работы со списком
Это не ускорение работы со списком, а создание помеси бульдога с носорогом - зачем?

Суть списка - последовательный доступ к элементам и в этом разрезе список работает быстрее массива, поскольку взятие следующего элемента осуществляется по уже хранимому в памяти указателю против вычисления следующего адреса в массиве.
Суть массива - произвольный доступ к элементам и в этом массив выигрывает у списка ибо для обращения к элементу массива нужно лишь вычислить адрес элемента против прохода от головы/хвоста/сохраненной текущей позиции до требуемого элемента.

Вывод: если алгоритм подразумевает последовательный обход элементов, то выбирайте список, если же алгоритм требует постоянного обращения к элементам по произвольным индексам - выбирайте массив. Например: большинство алгоритмов сортировки для списка будут быстрее чем для массива, но за эту скорость приходится платить памятью для хранения помимо данных еще и указателей связывающих элементы списка, массивы же не требуют дополнительной памяти (то есть они легче) и выборка элементов по индексам для них дешевле. Собственно потому, например, очереди и стэки предпочтительнее строить на списках, а ассоциативные контейнеры на массивах.

Если же так велико желание получить преимущества обоих вариантов, то более верным подходом будет использование чего-то одного, а в случаях когда будут уместны преимущества второго построить это второе на основе первого. Например: в некоем приложении работаете со списком поскольку в основном требуется последовательный доступ, но возникает ситуация когда требуется многократно выполнить серию операций требующих произвольного доступа, тогда выпускаете на основе списка массив указателей на его элементы и выполняете обработку - по мере надобности массив можно уничтожать и выпускать заново.
1
76 / 68 / 10
Регистрация: 11.07.2016
Сообщений: 320
30.10.2020, 20:40
Цитата Сообщение от Annemesski Посмотреть сообщение
Суть списка - последовательный доступ к элементам и в этом разрезе список работает быстрее массива
Это очень сильное заявление. Навскидку, разыменовывание стоит заметно дороже одной операция сложения.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12931 / 6799 / 1820
Регистрация: 18.10.2014
Сообщений: 17,211
30.10.2020, 20:52
Цитата Сообщение от Annemesski Посмотреть сообщение
Суть списка - последовательный доступ к элементам и в этом разрезе список работает быстрее массива, поскольку взятие следующего элемента осуществляется по уже хранимому в памяти указателю против вычисления следующего адреса в массиве.
Что за невероятная феерическая белиберда?

Вычисление следующего адреса в массиве - на порядки (!) более легкая и эффективная операция, чем тяжеленное чтение готового значения указателя на следующий элемент из памяти.

Более того, последовательный доступ к массиву астрономически боле эффективен еще и потому, что элементы массива гарантированно расположены один за другим в памяти, что делает массив идеальной кэш-дружественной структурой данных. Для списка этого не гарантируется, что в общем случае просто убивает эффективность последовательного прохода по списку.

Цитата Сообщение от Annemesski Посмотреть сообщение
Например: большинство алгоритмов сортировки для списка будут быстрее чем для массива,
В реальности же все наоборот.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9005 / 4706 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
30.10.2020, 21:31
Annemesski, не горюйте. Список видит своих защитников) Мы им ответим. Так вот например:
Сколько список не корми, а у него итераторы всегда валидны.То есть: Удаляй не удаляй, а всё равно получишь - валидный итератор.
Но нельзя путать лист с шарпом. У них ilist не лист ienumerable не 'энумерабле. Крибле- крабле и те списки, что ArrayList и List<T> на поверку массивы (внутренне). Это наверное, чтобы ни кто не догадался. А списки у них живут во в таких местах:
https://docs.microsoft.com/en-... etcore-3.1
LinkedList<T> - о -как !
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9005 / 4706 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
30.10.2020, 21:45
del дубликат
0
 Аватар для Annemesski
2670 / 1333 / 479
Регистрация: 08.11.2016
Сообщений: 3,683
30.10.2020, 21:55
TheCalligrapher, TheCalligrapher, как на счет вычисления и разыменования? Или в массивах указатели разыменовывать не надо?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12931 / 6799 / 1820
Регистрация: 18.10.2014
Сообщений: 17,211
30.10.2020, 22:32
Цитата Сообщение от Annemesski Посмотреть сообщение
как на счет вычисления и разыменования? Или в массивах указатели разыменовывать не надо?
1. "Разыменование"? Разыменование, что есть чтение (или запись) полезного значения элемента из памяти присутствует в одинаковой мере и в массиве, и в списке. То есть в общем итоге в массиве такое разыменование одно, а в списке их два. Замечаете разницу?

Однако, еще раз, как я сказал выше, в массиве разыменование в общем случае намного более эффективно, ибо массив лежит в памяти последовательно, т.е. обладает идеальнейше дружественным поведением по отношению к процессорному кэшу и к механизмам prefetch. А это один из самых важных факторов эффективности.

2. "Вычисления"? Я же ясно сказал выше: вычисление адреса элемента массива - на порядки более эффективная операция, чем чтение указателя из памяти.
0
 Аватар для Annemesski
2670 / 1333 / 479
Регистрация: 08.11.2016
Сообщений: 3,683
30.10.2020, 23:05
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
вычисление адреса элемента массива - на порядки более эффективная операция
с этим я и не спорил
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
а в списке их два.
посыпаю голову пеплом.

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

ПС: Ок, лучший ответ снимаю.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9005 / 4706 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
31.10.2020, 00:58
Цитата Сообщение от Annemesski Посмотреть сообщение
Получается списки эффективнее только там где требуются вставки и удаления элементов и перемещения элементов в случаях хранения тяжелых объектов и все это при условии что остальные операции требуют преимущественно последовательный доступ к элементам, в противном случае даже для тяжелых объектов скорее массив указателей (в котором тоже будет два разыменования) окажется более эффективным.
Не только. И возможно даже не столько. Список хорош стабильностью итераторов. Кроме того, он хорош возможностью выделения памяти по-элементно. Это и слабость и сила. Например, в случае реализации цепочек (backets) для хеш-таблиц, есть предположение (надежда), что коллизий не должно быть много, но тем не менее не известно в каком месте возможно сильное отклонение от среднего. Тут сочетание экономности и медлительности вполне оправдано. И еще важен случай, когда список может разворачиваться в тип элемента. В языке JAM строка - основной тип и списки строк - основной контейнер. Гибкость этого языка поразительна.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
31.10.2020, 00:58
Помогаю со студенческими работами здесь

Относительное указание адреса на файл
В одном решении 2 проекта, при запуске первого должен создаваться json-файл в одной папке с исполняемым файлом данного проекта, второй...

Выделение памяти для указателя
Помогите пожалуйста разобраться в одном примере: #include &quot;stdafx.h&quot; #include &lt;iostream&gt; using namespace std; int main() { ...

указание адреса при загрузки изображения
как загрузить в picturebox изображение без указания пути к нему? на разных компах при загрузке проекта соответственно получаются разные...

Указание первоначального адреса элемента массива
Был дан массив из 3-х разрядных чисел,необходимо было найти суммы цифр каждого числа и выстроить их по убыванию с указанием их...

Как закрыть все соединения для определенного IP адреса ?
Передаю в аргументы IP адрес + порт, например так: /root/test_script 127.0.0.1 80 Как скриптом закрыть все соединения данного IP адреса...


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru