Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 5.00/6: Рейтинг темы: голосов - 6, средняя оценка - 5.00
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
1

Реальная затрачиваемая память в динамике

15.09.2016, 06:30. Показов 1065. Ответов 21
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Динамическое выделение памяти.. допустим есть:
C++
1
int *ivar=new int[255] ;
Поидее при выделении должно выделиться 255*4 байт памяти, однако при использовании delete программа заведомо знает данный размер (255*4), а значит этот размер где то хранится. Так вот, для хранения размера чисто логически - значит положена ещё одна переменная. (при этом подозреваю, что при 32б архитектуре эта переменная будет 4 байтной, т.к. в 4 байта влазиет адрес максимума 4ГБ, соответственно в 64б арх. - переменная будет 8 байтной).
Ну и получается, что по крайней мере помимо 255*4 байт, выделяется ещё 4 байта, которые будут хранить размер. Но ведь и это по сути может быть не предел, может там есть ещё какие то необходимые поля.
Может кто знает, или где почитать? (т.к. ссылки на другие сайты запрещены, можете выложить ключевую фразу для гугла или яндекса, чтоб сразу найти)

Почему собственно данный вопрос возник.. Сижу разбираю статью о кастомных аллокаторах ("Альтернативные аллокаторы памяти" на хабре), где достаточно интересно представленны манипуляции с выделением памяти.. при использовании обычных аллокаторов new и calloc никогда и не задумываешся о том, что же на самом деле происходит "внутри", а ведь это достаточно интересно).

Так вот, и подумалось.. а зачем собственно нам нужны все эти union'ы и варианты, где вечно встаёт вопрос о "неиспользуемой памяти" при выделении памяти для POD типов меньших размеров чем сами структуры. Не проще ли было бы использовать указатель смещения, в место того, чтоб полагаться на устройство ОС в отношении выделяемых объектов.
Имею ввиду что то типа переменной uint8_t *mem в примере из статьи:
C++
1
2
3
4
5
typedef struct _LinearBuffer {
uint8_t *mem;       /*!< Pointer to buffer memory. */
uint32_t totalSize; /*!< Total size in bytes. */
uint32_t offset;    /*!< Offset. */
} LinearBuffer;
А если мы можем сами контролировать реальные размер памяти, то и меньше проблем было бы с размером и фрагментацией.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
15.09.2016, 06:30
Ответы с готовыми решениями:

PaintBox в динамике
Привет всем! Изучая компонент Paintbox, возник вопрос - как можно применить ему следующие моменты:...

Задача по динамике
Помогите, пожалуйста, с решением этой задачи. Я с таким сталкиваюсь впервые. Думал, что можно...

Задача по динамике
Доброго дня, Сижу ломаю голову с задачей, не знаю как и с чего начать (в динамике плыву очень...

Задача по Динамике
Здравствуйте, помогите пожалуйста решит следующий задачу Дрезина массы m = 500 кг движется по...

21
Эксперт по математике/физикеЭксперт С++
2048 / 1366 / 395
Регистрация: 16.05.2013
Сообщений: 3,505
Записей в блоге: 6
15.09.2016, 07:27 2
Цитата Сообщение от Izual Посмотреть сообщение
А если мы можем сами контролировать реальные размер памяти, то и меньше проблем было бы с размером и фрагментацией.
Хотите сами контролировать объем выделенной памяти используйте API ОС, а не стандартный С++.
0
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
15.09.2016, 08:03  [ТС] 3
Цитата Сообщение от Ilot Посмотреть сообщение
API ОС
В смысле VirtualAlloc или что вы имеете ввиду?

Как бы аллоктор new/delete (подозреваю что и calloc/malloc/realloc/free тоже) сделан на базе этой функции. Но это опять же уровень вверх, а что там под копотом VirtualAlloc?
0
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
17.09.2016, 09:50  [ТС] 4
Тема что то так и не раскрыта.
(я вот честно не знаю что взять в пример.. calloc или new, так что берите что хотите.. я не особо хорошо понимаю в чём собственно различие, потому как кроме как exception'а и _msize по факту мало что бросается в глаза после прочтения с 50 всяких статей)
Тогда начнём по порядку. (тема для windows 32разрядной и MSVC компилятора)
1) Оператор(аллокатор) new использует VirtualAlloc?
2) Читал что VirtualAlloc выделяет из общей ОЗУ блоки от 64 кбайт, то получается что при каждой операции выделении памяти через new где то в компиляторе(или где то ещё?) сидит некая оболочка(структура или класс?) которая должна поидее хранить: тип переменной, размер массива(если это массив или 1) и адрес. Так что же, получается что в реальности, для хранения любой переменной, созданой динамически - будет дополнительно израсходованно по мимо памяти для данных самой переменной (для начала только POD типы, т.е. от 1 до 8 байт) будет ещё 1 байт на тип, 4 байта на размер PTR, и собственно адрес ячейки в выделенной странице памяти, ах ну да, ещё и номер страницы.. так что ли?
Или чуточку сложнее, и к примеру:
на тип выделяется 2^4(4 бита, побитовыми операторами)(значение в 16 должно хватить)
массивы выделяются отдельно, например как двух сторонний стэк.. т.е. при выделении обычной переменной(не массив), мы можем не тратить 4 байта на размер, а с другой стороны стэка тратим(для массива).
адрес.. 4 байта? (или можно обойтись 2 байтами, т.к. у нас предел это одна выделенная страница)
страница - фиг знает, походу надо 4гб разделить на 64 кб, т.е. если сойдётся, то 2 байта, если нет - то 4 байта)


Добавлено через 8 минут
П.С. Кстати, если мы заюзали 4 бита для типа, то можно ли оставшиеся 4 бита "прилепить" к адресу или странице? =)
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
17.09.2016, 10:10 5
Цитата Сообщение от Izual Посмотреть сообщение
1) Оператор(аллокатор) new использует VirtualAlloc?
new/malloc - это "умная" обертка над функциями системы для выделения памяти, не обязательно VirtualAlloc.

Цитата Сообщение от Izual Посмотреть сообщение
2) Читал что VirtualAlloc выделяет из общей ОЗУ блоки от 64 кбайт, то получается что при каждой операции выделении памяти через new где то в компиляторе(или где то ещё?) сидит некая оболочка(структура или класс?) которая должна поидее хранить: тип переменной, размер массива(если это массив или 1) и адрес.
Все немного не так.
Во-первых, информация о типе существует только на этапе компиляции.
Во-вторых, адрес хранить не нужно.
Пример:
C++
1
int * p = new int(123);
Здесь будет выделено несколько байт памяти, туда будет записано 123. Все.
Тип int существует только на этапе компиляции. Адрес записан в p, за его
хранение и очистку отвечает код программы. Потерял адрес - получил утечку.
0
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
17.09.2016, 12:51  [ТС] 6
Цитата Сообщение от Убежденный Посмотреть сообщение
информация о типе существует только на этапе компиляции
В смысле? У меня в ран-тайме переменные создаются. (ну понятное дело что указатель то инициализирован заранее)
Как может в ран-тайме не храниться инфа о размере переменной, если по значению указателя - берётся значение конкретного диапазона ячеек (1, 2, 4, 8 байт).. Запись как и чтение в конкретные ячейки происходят в ран-тайме, значит инфа хранится. И более того, если существует _msize() (правда не для ++new/delete, и он возвращяет размер выделенного PTR массива с учётом типа, то это лишь ещё раз указывает на это)
Цитата Сообщение от Убежденный Посмотреть сообщение
Потерял адрес - получил утечку.
В С/С++ нет встроенного функционала на авто-очистку, так что руками delete надо делать, так что нужно не просто адрес иметь, но и вызывать соответсвующую функцию (ну или оператор, который под копотом то всё равно имеет АПИ функцию ОС).
Хотя по поводу очистки памяти.. Если использовать ручной контроль VirtualAlloc, то подозреваю, что если контролировать страницы, то в случае потери адреса.. можно и автоматом всё почистить. (не уверен, но я ещё покапаю эту тему)
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
17.09.2016, 15:51 7
Цитата Сообщение от Izual Посмотреть сообщение
Как может в ран-тайме не храниться инфа о размере переменной, если по значению указателя - берётся значение конкретного диапазона ячеек (1, 2, 4, 8 байт)..
Потому что компилятор генерирует соответствующий код: для char 1 байт, для short 2 и так далее.
В динамике эта информация не хранится (исключение разве что для размера массивов).
0
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
17.09.2016, 20:57  [ТС] 8
Цитата Сообщение от Убежденный Посмотреть сообщение
компилятор генерирует соответствующий код: для char 1 байт, для short 2 и так далее.
Ну так и как же это происходит?
Как отличить что один указатель ссылается на 8 ячеек, другой на 16? И что конкретно вот эти ячейки следует читать и считать по правилам соответствующего типа? Т.е. если бы я функцию сделал SummFloat() и в него бы внёс правила для суммирования float..
0
Вездепух
Эксперт CЭксперт С++
11694 / 6373 / 1723
Регистрация: 18.10.2014
Сообщений: 16,057
17.09.2016, 21:09 9
Цитата Сообщение от Izual Посмотреть сообщение
Может кто знает, или где почитать?
Обсуждалось здесь и не раз. Бесстыже сошлюсь на себя

Можно ли обойти динамический массив не зная его размер?
Можно ли обойти динамический массив не зная его размер?
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
17.09.2016, 21:34 10
Цитата Сообщение от Izual Посмотреть сообщение
Ну так и как же это происходит?
Как отличить что один указатель ссылается на 8 ячеек, другой на 16?
Когда мы пишем '*p = 123;', компилятор "знает", что p - это
указатель на int, поэтому генерирует примерно такой код:
Assembler
1
2
mov eax, p
mov dword ptr [eax], 123; sizeof (dword) = 4
Вся информация о типах и размерах в C/C++ существует только на этапе компиляции.
Иначе были бы доступны такие фишки других языков, как рефлексия.
0
Вездепух
Эксперт CЭксперт С++
11694 / 6373 / 1723
Регистрация: 18.10.2014
Сообщений: 16,057
17.09.2016, 21:53 11
Цитата Сообщение от Izual Посмотреть сообщение
Как может в ран-тайме не храниться инфа о размере переменной,
Информация о размере переменной не хранится,как ран-тайм значение.

Она явно или неявно жестко "зашивается" непосредственно в сгенерированные компилятором процессорные инструкции. Для работы с 1-байтными данными используются процессорные инструкции для работы с 1-байтными данными. Для работы с 4-байтными данными используются процессорные инструкции для работы с 4-байтными данными. И т.д.

Если язык программирования поддерживает, например, 16-байтные целые числа, а машинная платформа не имеет процессорных инструкций для работы с целыми числами такой ширины, то компилятор будет генерировать некий более-менее нетривиальный набор инструкций для каждой операции с 16-байтными целыми. Опять же, этот набор инструкций будет жестко завязан на работу именно и только с 16-байтными целыми. Хранить и анализировать число 16 где-то в ран-тайме никто не будет.
0
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
18.09.2016, 04:07  [ТС] 12
Цитата Сообщение от Убежденный Посмотреть сообщение
компилятор "знает", что p - это
указатель на int
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Она явно или неявно жестко "зашивается" непосредственно в сгенерированные компилятором процессорные инструкции. Для работы с 1-байтными данными используются процессорные инструкции для работы с 1-байтными данными. Для работы с 4-байтными данными используются процессорные инструкции для работы с 4-байтными данными. И т.д.
Вы говорите одно и тоже, не давая отсылок или объяснения как это происходит. Ну вот и толку от того что это всё говорите - никакого. "Компилятор знает" звучит как реклама пельмешек(или чего там я хз, мясо не ем) "папа может".
0
Вездепух
Эксперт CЭксперт С++
11694 / 6373 / 1723
Регистрация: 18.10.2014
Сообщений: 16,057
18.09.2016, 08:18 13
Цитата Сообщение от Izual Посмотреть сообщение
Вы говорите одно и тоже, не давая отсылок или объяснения как это происходит.
Процитированный вами кусок моего поста - это и есть исчерпывающее объяснение того, что происходит. Дальше можно лишь вывалить вам сюда систему команд какого-либо конкрентного процессора в качестве иллюстрации. Но я не вижу в этом смысла, тем более что вы сами можете запросто посмотреть. Пример странслированного кода вот тоже уже привели в сообщении #10.

Что касается "компилятор знает"... Я не понимаю, что модет быть непонятноего в этом утверждении. Вы явно объявили некий указатель p как указатель на int: int *p. Затем вы передали это объявление на вход компилятору. Почему вас удивляет тот факт, что комплятор теперь знает, на данные какого размера указывает указатель p?

Если для вас это ничего не объясняет, то надо делать шаг назад и начинать с каких еще более азбучных азов. Мы просто еще не знаем, насколько далеко назад необходимо отступить.
1
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
18.09.2016, 09:50  [ТС] 14
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Вы явно объявили некий указатель p как указатель на int: int *p
А если я объявил указатель на void или union.
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Почему вас удивляет тот факт, что комплятор теперь знает, на данные какого размера указывает указатель p?
Потому что у меня вопрос о том памяти. В озу выделилось 4 байта для данных, а где информация о типе? С потолка он её не берёт..
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
систему команд какого-либо конкрентного процессора
Система команд отталкивается от типа. Где блин тип то хранится? Он же не на марсе хранится, а где то в памяти.
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Пример странслированного кода
и
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
процессорные инструкции для работы с 4-байтными данными
меня как то мало волнуют просто из того, что я и руками могу зайти на конкретный адрес и побитово вписать туда то что мне надо. А как я буду писать и считать предварительно эти биты - уже совершенно другая песня, думаю что вы и сами можете представить как. (по аналогии с тем как считаются "очень большие числа", которые не помещяются в 4 и 8 байтовые рамки)

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
насколько далеко назад необходимо отступить
В 90-ые, когда такие темы были актуальны.
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
18.09.2016, 10:27 15
Цитата Сообщение от Izual Посмотреть сообщение
В озу выделилось 4 байта для данных, а где информация о типе?
Ее нет. Какие проблемы? У нас есть указатель int на этот адрес.
Если где-то в коде встречается строка с разыменованием этого указателя, компилятор генерирует
вставку машинного кода с чтением sizeof (int) байт по этому адресу. Все. Зачем во время
выполнения программы хранить информацию о типе? Это лишнее. Лишние траты по памяти и
по эффективности.

Напомню, что 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
#include <cstdio>
#include <Windows.h>
#include <typeinfo>
 
struct foo {};
 
int main()
{
    //
    // Используем системную функцию выделения памяти: она
    // то уж точно ничего не знает про типы данных из C++.
    //
    PVOID Memory = VirtualAlloc(NULL, 4096, MEM_COMMIT, PAGE_READWRITE);
 
    int * p1 = (int *)Memory;
    char const * p2 = (char const *)Memory;
    foo * p3 = (foo *)Memory;
    
    printf("p1: %s\r\n", typeid(p1).name());
    printf("p2: %s\r\n", typeid(p2).name());
    printf("p3: %s\r\n", typeid(p3).name());
 
    return 0;
}
Вывод:
p1: int *
p2: char const *
p3: struct foo *
Адрес (Memory) один и тот же, а типы (p1, p2 и p3) "почему-то" разные...

Кстати, ассемблерный листинг сгенерированного кода (VC++2015) тоже весьма показателен.

Строка "int * p1 = (int *)Memory;" превращается в следующее:
Assembler
1
2
mov eax, DWORD PTR _Memory$[ebp]
mov DWORD PTR _p1$[ebp], eax
Как видим, в p1 копируется только значение указателя Memory,
никакой работы с типами нету.

А вот откуда берется строковое значение для "typeid(p1).name()":
Assembler
1
2
mov ecx, OFFSET ??_R0PAH@8
call ?name@type_info@@QBEPBDXZ ; type_info::name
Переменная ??_R0PAH@8 определена так:
Assembler
1
PUBLIC ??_R0PAH@8 ; int * `RTTI Type Descriptor'
То есть, информация о типе p1 уже "зашита" в исполняемый файл как 'int *'.
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,520
18.09.2016, 10:28 16
Цитата Сообщение от Izual Посмотреть сообщение
Система команд отталкивается от типа. Где блин тип то хранится?
а где хочет
это отдано на откуп компилятору, например VS перед выделенной памятью со смешением -4( вреде бы) плюс дебиговая версия создает еще и "подушки безопасности", для контролирования выхода за пределы массива
int *i =new int(123);
выделенный участок может выглядеть так
ppp 1 123 ppp
а может и по другому
без дизасемблирования не разберешься

вот попробуй такой хакерский трюк
C++
1
2
3
4
5
int *i =new int(123);
int *p=i-16;
int *e=i+16;
for(;p<e;p++)
 cout<<*p;
1
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
18.09.2016, 11:36  [ТС] 17
Цитата Сообщение от Убежденный Посмотреть сообщение
Зачем во время
выполнения программы хранить информацию о типе?
ПОТОМУ ЧТО ОН ОБРАЩЯЕТСЯ ТУДА. В ран тайм режиме записывается\читается переменная, что ж неясного-то.
Цитата Сообщение от Убежденный Посмотреть сообщение
информация о
типах определяется на этапе компиляции и далее никогда не меняется
Да не надо её менять. Да, на этапе компиляции заносятся данные куда то на потолок, что PTRqweINT = имеет тип int указателя, но как она определяется в ран тайме, что начиная с ХХХХFFFF байта в ОЗУ - именно PTRqweINT, а не PTRasdCHAR.
Чисто логически невозможно не тратя доп. памяти не указывать что там именно INT PTR, а не собака на сене.
Дальше по посту.. вроде интересно - но бесполезно полностью.

ValeryS, ВОТ! Твоё предположение выглядит вполне логично, что где то там в памяти имеются ряд ячеек(перед каждым значением например, т.е. если указатель ссылается на XX, то данные будут 1 ячейкой ранее), которые отвечают за типы\размеры\что то там ещё..

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

Добавлено через 14 минут
Добавлю..
Цитата Сообщение от Убежденный Посмотреть сообщение
Адрес (Memory) один и тот же, а типы (p1, p2 и p3) "почему-то" разные...
Вот.. это говорит о том, что инструкция DWORD ассемблерного листинга вызывается потому что "вшитые" данные относятся к определению переменной PTRqweINT. Т.е. в начале работы программы выделяется память, куда записываются данные о типах объявленных переменных, в данном случае - это указатель на INT. Значит что данные переменной и тип переменной могут(а скорее всего так и есть) находиться совершенно в разных местах, и место для данных переменной которое выделено с помощью VirtualAlloc совершенно не имеет зависимости с местом, где хранится тип(type_id) этой PTRqweINT.
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,520
18.09.2016, 11:42 18
Цитата Сообщение от Izual Посмотреть сообщение
значит если несколько ячеек выделены под инф. о переменной,
а вот это нет
может и без типа
вот кусок дизасемблированой проги
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 mov     eax, [ebx+4]
.text:00D608AB                 cmp     eax, esi
.text:00D608AD                 jnz     short loc_D608B2
.text:00D608AF                 mov     [ebx+0Ch], esi
.text:00D608B2
.text:00D608B2 loc_D608B2:                             ; CODE XREF: sub_D60820+8Dj
.text:00D608B2                 mov     edx, [ebx+8]
.text:00D608B5                 cmp     edx, esi
.text:00D608B7                 jnz     short loc_D608BC
.text:00D608B9                 mov     [ebx+10h], esi
.text:00D608BC
.text:00D608BC loc_D608BC:                             ; CODE XREF: sub_D60820+97j
.text:00D608BC                 cmp     eax, esi
.text:00D608BE                 jnz     short loc_D608CF
.text:00D608C0                 cmp     edx, esi
.text:00D608C2                 jnz     short loc_D608C7
.text:00D608C4                 mov     [ebx+2Ch], esi
видно что ebx указывает на кусок памяти а по определенным смещением происходят модификации
чтение/запись/ сравнения
а что там лежит? структура? класс? массив? а процессору по барабану он числа записывает или считывает
все это сделал компилятор
причем для ARM процессора код будет совершенно другим
чтобы понять логику человеку приходится вручную разгребать
почитай книгу "Искусство дизасемблирования" К. Касперски, там эти вопросы рассматриваются
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
18.09.2016, 19:49 19
Цитата Сообщение от Izual Посмотреть сообщение
Тут походу даже мат не поможет.. матерись не матерись.. ну если человек не видит вопроса.. очки думаю тоже не помогут.
Вопрос прозвучал так, цитирую дословно:

Цитата Сообщение от Izual Посмотреть сообщение
Так что же, получается что в реальности, для хранения любой переменной, созданой динамически - будет дополнительно израсходованно по мимо памяти для данных самой переменной (для начала только POD типы, т.е. от 1 до 8 байт) будет ещё 1 байт на тип, 4 байта на размер PTR, и собственно адрес ячейки в выделенной странице памяти, ах ну да, ещё и номер страницы.. так что ли?
На него тебе ответили так:

Цитата Сообщение от Убежденный Посмотреть сообщение
Вся информация о типах и размерах в C/C++ существует только на этапе компиляции.
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Информация о размере переменной не хранится,как ран-тайм значение.
По-моему, ответы и приведенные к ним примеры были исчерпывающие.

Цитата Сообщение от Izual Посмотреть сообщение
Цитата Сообщение от Убежденный
Зачем во время выполнения программы хранить информацию о типе?
ПОТОМУ ЧТО ОН ОБРАЩЯЕТСЯ ТУДА. В ран тайм режиме записывается\читается переменная, чтож блин не ясного то.
В рантайме читается только значение, но не тип. Тип/размер уже определен на этапе компиляции.
Ну я не знаю, как это объяснить "на пальцах". Я пас.

Цитата Сообщение от Izual Посмотреть сообщение
Да, на этапе компиляции заносятся данные куда то *(лять на потолок, что PTRqweINT = имеет тип int указателя, но как она определяется в ран тайме, что начиная с ХХХХFFFF байта в ОЗУ - именно PTRqweINT, а не PTRasdCHAR.
Никак не определяется.

Цитата Сообщение от Izual Посмотреть сообщение
Чисто логически невозможно не тратя доп. памяти не указывать что там именно INT PTR, а не собака на сене.
Да не нужна эта информация в рантайме. Не-нуж-на.
То, что там, к примеру, int, а не bool, компилятор использует для генерации кода.
В первом случае будет mov dword ptr, а во втором mov byte ptr.

Цитата Сообщение от Izual Посмотреть сообщение
Дальше по посту.. вроде интересно - но безполезно полностью.
Цитата Сообщение от Izual Посмотреть сообщение
П.С. значит если несколько ячеек выделены под инф. о переменной, то значит что помимо 4 байт например для данных, как минимум ещё 1 байт выделяется. (жаль что нет инфы сколько же будет в конечном итоге)
Ничего там не выделяется. Только служебная информация для аллокатора памяти.

Цитата Сообщение от Izual Посмотреть сообщение
Вот.. это говорит о том, что инструкция DWORD ассемблерного листинга вызывается потому что "вшитые" данные относятся к определению переменной PTRqweINT.
Нет, не так. Компилятор видит, что там int, и генерирует код с DWORD. Это все
происходит на этапе компиляции, повторю. В рантайме уже никаких проверок типов нету,
потому что это неэффективно. То же самое и с const, кстати говоря. Представь себе
какую-нибудь числодробилку: расчет хэшей, кодирование медиа-потока, шифрование и т.п.
Если бы там на обращение к каждому DWORD-у была проверка типа, то мы бы видео ни в
одном плеере, написанном на C++, не могли бы смотреть. Ибо тормоза бы просто зашкаливали.

Цитата Сообщение от Izual Посмотреть сообщение
Т.е. в начале работы программы выделяется память, куда записываются данные о типах объявленных переменных, в данном случае - это указатель на INT.
Нет, ничего такого не делается. Можешь взять в руки дизассемблер и убедиться самостоятельно.
typeid(x).name(), пример которого я привел, определяет тип тоже статически (исключение -
классы с виртуальными таблицами и т.п.), т.е. по информации, взятой на этапе компиляции,
вставляется соответствущая текстовая строка. Там даже ветвлений нет.

Кстати, в стандарте языка вроде есть пункт, который оговаривает такие моменты
(поиск по ключевым словам "static type").

Цитата Сообщение от Izual Посмотреть сообщение
Значит что данные переменной и тип переменной могут(а скорее всего так и есть) находиться совершенно в разных местах, и место для данных переменной которое выделено с помощью VirtualAlloc совершенно не имеет зависимости с местом, где хранится тип(type_id) этой PTRqweINT.
Ну и какой же тип у данных, адрес которых вернула функция VirtualAlloc?
Я же тебе привел пример, где память и адрес ее начала один и тот же, а типы разные.
0
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
18.09.2016, 20:28  [ТС] 20
Цитата Сообщение от Убежденный Посмотреть сообщение
В первом случае будет mov dword ptr, а во втором mov byte ptr.
Ну сделаю я так (если это возможно):
C++
1
2
3
f(type_id == INT)
mov dword ptr
..
Тип всё равно где то вшит, а то что он "вшит" указывает на то что под это дело выделена память и где то это хранится.
Если мы вшиваем карман, то он будет реально существовать, вы же мне говорите что то типа: мы его вшили, но его не существует. Это же вздор!
Цитата Сообщение от Убежденный Посмотреть сообщение
Только служебная информация для аллокатора памяти.
И вней "вшит" тип?
Цитата Сообщение от Убежденный Посмотреть сообщение
Компилятор видит, что там int, и генерирует код с DWORD. Это все
происходит на этапе компиляции, повторю.
Всё равно где. Вшито было на этапе компиляции, но извлечение данных идёт в ран-тайме. Потому что я в ран-тайме создаю 100500-ый экземпляр этой PTRqweINT.
Цитата Сообщение от Убежденный Посмотреть сообщение
адрес которых вернула функция VirtualAlloc?
Это Вы откуда взяли?
0
18.09.2016, 20:28
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
18.09.2016, 20:28
Помогаю со студенческими работами здесь

PaintBox в динамике 2
Здравствуйте, уважаемые жители форума. Некоторое время назад мною был заданы вопросы по теме...

Отчет по динамике
Добрый день. Подскажите как лучше сделать отчет по динамике показателей от недели к недели? Это...

Задача по динамике
Как решать эту задачу?

Обьект в динамике
Всем привет ! Скажите пожалуйста , есть ли необходимость перем. х класса Miva ложить в...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru