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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.80
kordax
4 / 4 / 1
Регистрация: 08.06.2014
Сообщений: 89
#1

Выделение памяти по известному адресу - C++

20.07.2014, 22:22. Просмотров 1543. Ответов 29
Метки нет (Все метки)

Всем привет.

Вопрос сообственно в заголовке темы.
Как выделить память по нужному мне адресу, например:
Я хочу выделить память n* sizeof(T) по адресу 0x7fff2b98c30c
Сделать это нужно для того, чтобы я всегда потом мог обратиься к элементу, который там располагается.

И второй вопрос:
Как потом получить объект по этому фиксированному адресу?
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.07.2014, 22:22
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Выделение памяти по известному адресу (C++):

Вызвано исключение по адресу 0x0FD466CB (ucrtbased.dll). Динамическое выделение памяти - C++
Проблема в динамическом выделении памяти. Функция multiply доходит до возвращения объекта и вылетает исключение. Если функция вернет просто...

Чтение и запись значения по известному адресу - C++
Нужно реализовать чтение и запись переменной по адресу. Конкретно: есть флеш-игра, есть программа Cheat Engine, и есть значение в этой...

Общий параметр для всех классов и создание объекта по известному адресу - C++
Вообщем есть задание. Скажу сразу, вся реализация для меня понятна, за исключением одного момента. Поидее, мне нужен счётчик,...

Распределение памяти. Динамическое выделение памяти - C++
an-1 an-2 ... a2

Выделение памяти, проверка на утечку памяти - C++
Интересуют два вопроса: 1. Правильно ли устроен алгоритм выделения, удаление и запись ячейки памяти? Может быть, есть более простые...

Прочитать из памяти по адресу - C++
Задача: в памяти по адресу 0040:0010h (0x00400010) записано слово (информация о подключенном оборудовании). Нужно прочитать 12-й бит этого...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
kordax
4 / 4 / 1
Регистрация: 08.06.2014
Сообщений: 89
20.07.2014, 23:20  [ТС] #16
Смысл в том, что я уцепился за это задание и хочу так сделать
Счетчик ссылок должен быть синглтоном,
Можно поподробнее
0
DrOffset
7154 / 4295 / 971
Регистрация: 30.01.2014
Сообщений: 7,100
20.07.2014, 23:23 #17
Цитата Сообщение от kordax Посмотреть сообщение
Смысл в том, что я уцепился за это задание и хочу так сделать
Пока что, если честно, не совсем понятно так, это как
Цитата Сообщение от kordax Посмотреть сообщение
Можно поподробнее
Можно, только то, о чем я говорил, мне кажется все-таки отличается от того, что хотел ты. Поэтому давай сначала ты расскажешь о том, как ты такой класс хочешь применять. Пример, который был выше не очень походит на использование shared_ptr (в любом варианте), т.к. нет никакого смысла считать объект на стеке (int x).
0
IIARTEMII
20 / 20 / 3
Регистрация: 14.06.2012
Сообщений: 95
Завершенные тесты: 1
20.07.2014, 23:43 #18
Цитата Сообщение от kordax Посмотреть сообщение
Я хочу выделить память n* sizeof(T) по адресу 0x7fff2b98c30c
Возможно на очень низком уровне (я где-то читал реализацию менеджмента памяти на винде, там можно было конкретную область памяти проверить на занятость и, если она свободна, то мы её занимаем).
Но если вы лично не хотите задавать какой-то адрес, а просто выделяете память и хотите в эту память что-то положить, то "placement new" Вам в помощь.
В стандарте, например, сказано, что:
C++
1
2
void* place = operator new(sizeof(Something)); // 1
Something* p = new (place) Something(); // 2
1 - выделяет память и возвращает нам указатель; 2 - размещает конкретный объект в этой области памяти. Это что-то типа использования malloc, но C++ вариант.
Со статической памятью можно аналогично:
C++
1
2
3
char buffer[100];
void *ptr = (void*)buffer;
Something *p = new(ptr) Something();
Тут память освобождать не надо; В этом операторе new очень расплывчатая формулировка использования... данные, которые многие папки программисты приводят по всему интернету, зачастую противоречат друг другу. В стандарте дан тот минимум, который необходим для использования, а дальше берём и тестируем на утечки, на правильность размещения и вообще смотрим механику работы этого оператора в конкретной реализации конкретного компилятора
1
kordax
4 / 4 / 1
Регистрация: 08.06.2014
Сообщений: 89
21.07.2014, 00:17  [ТС] #19
Мне нужно всё осмыслить)).
Ради прокачки я кстати и хотел создать такой мазохистский класс, чтобы просто понять, как это возможно.
С практической точки зрения я его применять не буду, это просто задание из книги Страуструпа.
0
DrOffset
7154 / 4295 / 971
Регистрация: 30.01.2014
Сообщений: 7,100
21.07.2014, 00:53 #20
Цитата Сообщение от kordax Посмотреть сообщение
С практической точки зрения я его применять не буду, это просто задание из книги Страуструпа.
Ну Страуструп вряд ли подразумевал такое использование, как ты тут описал.
Вообще я попросил пример использования для того, что бы лучше понять что тебе нужно и что ты хочешь. Правильно сформулированный вопрос содержит половину ответа
0
IIARTEMII
20 / 20 / 3
Регистрация: 14.06.2012
Сообщений: 95
Завершенные тесты: 1
21.07.2014, 01:11 #21
Ай, ай, ай! Посмотрите VirtualAlloc в MSDN =)) это ровно то, что Вам нужно (на тему об использовании КОНКРЕТНОГО адреса)

Добавлено через 4 минуты
Ещё я внезапно загуглил mmap - для unix
0
DrOffset
7154 / 4295 / 971
Регистрация: 30.01.2014
Сообщений: 7,100
21.07.2014, 02:53 #22
IIARTEMII, ну вот зачем это советовать? В VirtualAlloc задается адрес границы блока. Если там задан другой адрес, то он округляется до ближайшей границы блока. В общем, это не о том и не за тем
MSDN:
The starting address of the region to allocate. If the memory is being reserved, the specified address is rounded down to the nearest multiple of the allocation granularity. If the memory is already reserved and is being committed, the address is rounded down to the next page boundary.
А mmap - это отображение в память устройств или файлов. Аналог в windows - MapViewOfFile.
0
IIARTEMII
20 / 20 / 3
Регистрация: 14.06.2012
Сообщений: 95
Завершенные тесты: 1
21.07.2014, 10:49 #23
DrOffset,
MSDN:
VirtualAlloc function

Reserves or commits a region of pages in the virtual address space of the calling process. Memory allocated by this function is automatically initialized to zero...
...
The VirtualAlloc function can perform the following operations:
  • Commit a region of reserved pages
  • Reserve a region of free pages
  • Simultaneously reserve and commit a region of free pages
...
You can use VirtualAlloc to reserve a block of pages and then make additional calls to VirtualAlloc to commit individual pages from the reserved block...
Как бЭ...
Аналогично и с mmap, только для unix
И, да, что мешает сравнить адрес, который нам вернула функция с нашим заданным адресом? не совпал - освобождаем или используем другой. На высоком уровне это, вроде бы, единственный способ получить в своё распоряжение заданный нами кусок виртуальной памяти. На низком уровне получите все данные о процессе, который занимает данный кусок памяти, лишите его этого куска, отдайте ему другой, расскажите ему об этом, а себе зарезервируйте отобранный. Тем более, где-то (опять же) читал, что в защищенном режиме при работе с памятью процессу можно просто указать новый физический адрес блока памяти для виртуального блока, при этом оставив все виртуальные адреса на месте.

Добавлено через 3 минуты
с mmap, конечно, история не напрямую только с памятью связана, тут мы выходим из ситуации при помощи файла
0
uglyPinokkio
326 / 229 / 41
Регистрация: 30.05.2014
Сообщений: 682
21.07.2014, 11:00 #24
Цитата Сообщение от kordax Посмотреть сообщение
Я всё пытаюсь реализовать shared_ptr, но на просторах интернета нету совершенно ни одной нормальной реализации
Современное проектирование на C++ Андрей Александреску.
Если мне склероз не изменяет - их там было.
0
DrOffset
7154 / 4295 / 971
Регистрация: 30.01.2014
Сообщений: 7,100
21.07.2014, 18:09 #25
IIARTEMII, ну нет же. даже в том что ты процитировал, ключевое слово pages. VirtualAlloc работает со страницами, а не с конкретными адресами. Я же выделил жирным выше.

Цитата Сообщение от IIARTEMII Посмотреть сообщение
Аналогично и с mmap, только для unix
Mmap берет файл и отображает его на адресное пространство, позволяя усуществить произвольный доступ к файлу на чтение или запись посредством адресации в памяти. Т.е. память выделена большим блоком, достаточным для адресации заданного файла. С таким же успехом мы можем просто вызвать new в начале программы, выделив достаточно большой участок памяти, и на нем уже сделать свой собственный аллокатор или пул, который позволит выбрать произвольный незанятый адрес в пределах этого блока. Т.е. это настолько очевидно и не нужно связываться с никакими дополнительными инструментами. Но автор, очевидно, хотел совсем другого.

Добавлено через 4 минуты
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
Современное проектирование на C++ Андрей Александреску.
Если мне склероз не изменяет - их там было.
Если ему бустовская показалась сложной, то Александреску тоже не понравится
0
IIARTEMII
20 / 20 / 3
Регистрация: 14.06.2012
Сообщений: 95
Завершенные тесты: 1
21.07.2014, 19:14 #26
DrOffset, сколько людей, столько мнений; почему мы не можем, опираясь на
the return value is the base address of the allocated region of pages
использовать этот адрес для хранения нашей информации?
По-моему, всё очень даже хорошо
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
#include <windows.h>
 
#include <iostream>
#include <conio.h>
 
using namespace std;
 
int main() {
    void *pmem = VirtualAlloc((void*)(0x260000), 4096, MEM_RESERVE, PAGE_READWRITE);
    if (!pmem)
        return -1;
    void *_pmem = VirtualAlloc((void*)(0x260000), 4096, MEM_COMMIT, PAGE_READWRITE);
    if (!_pmem) {
        VirtualFree(pmem, 0, MEM_RELEASE);
        return -1;
    }
    int *ptr = (int*)_pmem;
    *ptr = 3;
    cout << ptr << endl << *ptr << endl;
    _getch();
    VirtualFree(_pmem, 4096, MEM_DECOMMIT);
    VirtualFree(pmem, 0, MEM_RELEASE);
    return 0;
}
Я только немного не пойму про переносимость этого кода... Иногда работает RESERVE, иногда COMMIT, а иногда оба вместе. В любом случае, при неудаче мы уходим. Если убрать проверку на 10 строчке, то код работает очень переносимо, но сбои иногда появляются. Вообщем интересный вопрос, надо думать; а то, что Вы писали про округление - почитайте ещё, либо я Вас не понял, сколько ни прочту, либо Вы немного не так поняли иностранный язык
0
DrOffset
7154 / 4295 / 971
Регистрация: 30.01.2014
Сообщений: 7,100
21.07.2014, 19:19 #27
Цитата Сообщение от IIARTEMII Посмотреть сообщение
а то, что Вы писали про округление - почитайте ещё, либо я Вас не понял, сколько ни прочту, либо Вы немного не так поняли иностранный язык
Я цитату подсветил же выше.
rounded down to the nearest multiple of the allocation granularity
Что конкретно здесь не понятно и в чем противоречие с моими словами? Слово "округление" можно заменить на слово "выравнивание". Смысл не поменяется. VirtualAlloc низкоуровневая функция для манипуляции страницами памяти. Размер страницы на x86 32-бита равен 4Kb. Ничто не настораживает? Как минимум предложение использовать эту функцию для выделения памяти для одной переменной выглядит странно.
Цитата Сообщение от IIARTEMII Посмотреть сообщение
использовать этот адрес для хранения нашей информации?
Да можешь, только это совсем не конкретный адрес, как ты выше написал. Вот же твоя цитата:
Цитата Сообщение от IIARTEMII Посмотреть сообщение
на тему об использовании КОНКРЕТНОГО адреса
Совсем не в любом случае он будет именно тем, что ты задал. Да и использовать это для задачи ТС - это из пушки по воробьям как минимум.
Цитата Сообщение от IIARTEMII Посмотреть сообщение
Я только немного не пойму про переносимость этого кода...
Этот код вообще не переносим (в общепринятом смысле слова "переносимость"), т.к. опирается на свойства и API платформы windows.
0
IIARTEMII
20 / 20 / 3
Регистрация: 14.06.2012
Сообщений: 95
Завершенные тесты: 1
21.07.2014, 19:38 #28
Мои сообщения в большей мере о windows (так как ТС не задал конкретных рамок, вполне имею право), под переносимостью я имею в виду версию (XP, win7, win8 и их вариации).
Цитата Сообщение от DrOffset Посмотреть сообщение
Размер страницы на x86 32-бита равен 4Kb. Ничто не настораживает?
Ничего, совершенно
Цитата Сообщение от DrOffset Посмотреть сообщение
только это совсем не конкретный адрес
Совсем конкретный адрес, но не физический, о чём и была речь
Цитата Сообщение от DrOffset Посмотреть сообщение
Совсем не в любом случае он будет именно тем, что ты задал
Если он свободен - будет именно он, если его выровнять, опираясь на соглашение о виртуальной адресации памяти и выравнивании страниц

Добавлено через 8 минут
Что спорить, если я реализовал резервирование под свои нужды конкретно указанного мной участка виртуальной памяти и использовал его для чтения и записи данных?
Вопрос был:
Цитата Сообщение от kordax Посмотреть сообщение
Как выделить память по нужному мне адресу, например:
Я хочу выделить память n* sizeof(T) по адресу 0x7fff2b98c30c
Это сделано. Тут есть подводные камни, да (например, что выделяться будут блоки памяти с округлением до 4kb), но это сделано. Вопросы?
0
DrOffset
7154 / 4295 / 971
Регистрация: 30.01.2014
Сообщений: 7,100
21.07.2014, 19:53 #29
IIARTEMII, твоя точка зрения понятна. Спорить дальше смысла не вижу, т.к. я уже в общем-то все сказал.

Добавлено через 11 минут
Цитата Сообщение от IIARTEMII Посмотреть сообщение
Вопросы?
Только один. Советовать частное решение с подводными камнями человеку, который захотел странного из-за неправильного понимания концепции shared_ptr - зачем? Вместо того чтобы объяснить ситуацию, указать на ошибки, приводится вариант, который создает иллюзию возможности общего решения первоначально ошибочного вопроса.
Цитата Сообщение от IIARTEMII Посмотреть сообщение
но это сделано.
В инженерии средства должны соответствовать решаемой задаче. А не быть из разряда "сделать любой ценой". Можно забивать гвозди и микроскопом, но он для этого не предназначен. Есть простое правило, "если задача сопротивляется решению, значит она была неверно поставлена".
0
IIARTEMII
20 / 20 / 3
Регистрация: 14.06.2012
Сообщений: 95
Завершенные тесты: 1
21.07.2014, 20:09 #30
Последнее моё слово в этой теме: с помощью предложенного мной метода можно выделять под себя даже 1 байт памяти; подводных камней тут не будет, если понимать, как работает распределение памяти. Человек захотел странного - он это получил, почему бы и нет? А решение не частное) Если программируете под windows, то Вы сами его используете, хоть и не догадываетесь об этом... все мы это используем
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.07.2014, 20:09
Привет! Вот еще темы с ответами:

Данные по адресу памяти - C++
У меня есть адрес например 0x11E9B62C как узнать что по нему записанно?

Доступ к памяти по адресу - C++
Есть структура, элементы которой адрес на начало массива в памяти и его размер. Адреса хранятся в 16-ричном формате. Мне нужно распечатать...

Доступ к произвольному адресу памяти - C++
Есть известный адрес в памяти с известным значением int Хотел бы проверить это значение после того как введу адрес памяти вручную. ...

Взятие обьекта по адресу в памяти - C++
Допустим, я знаю что по адресу 0x13242341 находится произвольный обьект. Как возвратить указатель типа void на данный адрес Типо так?...


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

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

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