1

Тема: Як визначити скільки памяті займає об'єкт?

Я знаю, що є оператор sizeof, але мене цікавить, чи можна написати свій аналог?
Тобто, чи можна десь подивитися на реалізацію sizeof, ну, чи на те, як він працює?

2 Востаннє редагувалося koala (03.09.2020 16:49:01)

Re: Як визначити скільки памяті займає об'єкт?

Можете пояснити, що саме ви збираєтеся робити? Можете навести приклад коду, в якому вам потрібен цей аналог замість звичайного sizeof?
Реалізацію можете подивитися у вихідному коді компілятора, але навіщо? Що саме не зрозуміло з його роботою?

sizeof насправді вбудований досить глибоко в структуру мови. C++ активно покладається на арифметику вказівників, і неможливо знайти наступний елемент масиву без sizeof. Нащо його змінювати чи перевизначати?

3

Re: Як визначити скільки памяті займає об'єкт?

Ну, як я зрозумів sizeof працює лише в момент компіляції, а якщо я допустимо хочу дізнатися розмір під час виконання?
Не зовсім зрозуміло, як він реалізований всередині? Тобто є якісь дескрайбери для об'єктів?
Я не збираюся замінювати вбудований sizeof, а просто мати свою версію в додаток, не більше.

4 Востаннє редагувалося wander (03.09.2020 17:00:47)

Re: Як визначити скільки памяті займає об'єкт?

mimik написав:

Я знаю, що є оператор sizeof, але мене цікавить, чи можна написати свій аналог?

В загальному випадку - ні.

mimik написав:

Тобто, чи можна десь подивитися на реалізацію sizeof, ну, чи на те, як він працює?

Подивитися, напевно, так, як ви собі уявили не можна.

mimik написав:

Ну, як я зрозумів sizeof працює лише в момент компіляції, а якщо я допустимо хочу дізнатися розмір під час виконання?

Ем, що?
В статично типізованій мові не буває об'єкта без типу, а раз так, то достатньо знати розміру типу на етапі компіляції.
Якщо у вас об'єкт невідомого типу, і ви посилаєтеся на нього, наприклад через void-вказівник, то ніяк ви його розмір не визначите.

mimik написав:

Не зовсім зрозуміло, як він реалізований всередині? Тобто є якісь дескрайбери для об'єктів?

Який "дескрайбер"? Навіщо?

"Класичний" sizeof - конструкція часу компіляції. Компілятор знає розмір кожного типу. Звідси sizeof і знає, "скільки пам'яті займає об'єкт". Компілятор знає, що тип int має розмір 4. Тому sizeof(int) дає 4.

Все доволі просто.

Подякували: mimik, koala, leofun013

5

Re: Як визначити скільки памяті займає об'єкт?

Ага. Ну, все одно sizeof читає ім'я змінної і навіть в момент компіляції потрібно знати інформацію про об'єкт, значить вона ж десь записана ця інформація, чи ви хочете сказати що в момент компіляції відбувається пошук слова int?

6

Re: Як визначити скільки памяті займає об'єкт?

mimik написав:

Ага. Ну, все одно sizeof читає ім'я змінної і навіть в момент компіляції потрібно знати інформацію про об'єкт, значить вона ж десь записана ця інформація, чи ви хочете сказати що в момент компіляції відбувається пошук слова int?

Ні, під час компіляції складається таблиця символів програми, і там записано, що такий-то ідентифікатор - це int, а int має фіксований розмір.

mimik написав:

а якщо я допустимо хочу дізнатися розмір під час виконання?

А яким чином, вибачте, ви можете отримати розмір змінної під час виконання не таким, як під час компіляції?
От, власне, чому програмістам треба хоча б базове уявлення про асемблер мати - тоді такі питання просто не виникають.

Подякували: wander, mimik, 0xDADA11C7, leofun014

7 Востаннє редагувалося koala (03.09.2020 17:27:30)

Re: Як визначити скільки памяті займає об'єкт?

Ну, власне, є єдина ситуація, коли можна таки не знати розміру змінної під час компіляції - це виділення масиву у купі (new []). Тоді в службовій інформації купи зберігається, який розмір виділено, і до цього розміру в програміста немає доступу, треба десь окремо запам'ятовувати, є таке. Але досі це нікому суттєвих проблем не створювало.

8 Востаннє редагувалося Droid 77 (03.09.2020 17:36:51)

Re: Як визначити скільки памяті займає об'єкт?

mimik, що саме намагаєтесь зробити? Приведіть шматочок коду для прикладу, бо геть не зрозуміло що потрібно зробити.

9

Re: Як визначити скільки памяті займає об'єкт?

koala, дякую, загалом все зрозуміло.
Але ж наприклад під час роботи програми вже немає ніяких таблиць?

10

Re: Як визначити скільки памяті займає об'єкт?

mimik написав:

Але ж наприклад під час роботи програми вже немає ніяких таблиць?

Все вірно, ніяких таблиць з інформацією про розміри типів на етапі виконання не існує. На етапі виконання вже всюди фігурують тільки константи дбайливо підставлені компілятором в усі потрібні інструкції на етапі компіляції.

Подякували: koala, Droid 77, leofun013

11 Востаннє редагувалося Droid 77 (03.09.2020 18:02:19)

Re: Як визначити скільки памяті займає об'єкт?

Мова для того і існує щоб компілятор коректно перетворив бажання програміста в машинний код(інструкції).

12

Re: Як визначити скільки памяті займає об'єкт?

Уточню, бо це вочевидь потрібно. Інструменти нагуглив у два запити, можливо, є й зручніші.
Отже, процесор виконує байт-код. Приклад можете глянути тут: https://onlinedisassembler.com/odaweb/ - ліворуч шістнадцятковий запис байт-коду, праворуч - цей же код мовою асемблера.
https://godbolt.org/z/xhMEzj - перетворення коду на C++ в асемблер. Нас цікавлять лише 16 перших рядків: спершу - дані, потім - функція (далі іде код функції ostream::operator <<). Асемблерний код перетворюється на байт-код 1:1, тобто кожній інструкції відповідає конкретна послідовність байтів. І змінній a, яка в асемблері записується як

a:
        .long   5

буде відповідати послідовність байтів (шістнадцятковий запис)

05 00 00 00

4 байти - це і є розмір змінної. Коли ця змінна буде прочитана, то компілятор підставить відповідну операцію:

mov     eax, DWORD PTR a[rip]

І .long, і DWORD - це якраз про 4 байти; але на момент виконання буде точно відомо, скільки саме байтів і звідки треба прочитати.
Можете задля цікавості спробувати скомпілювати код із sizeof і переконатися, що в асемблері там буде число, а не операція.

Подякували: wander, mimik, leofun013

13 Востаннє редагувалося cheappi386 (04.09.2020 08:27:52)

Re: Як визначити скільки памяті займає об'єкт?

mimik написав:

koala, дякую, загалом все зрозуміло.
Але ж наприклад під час роботи програми вже немає ніяких таблиць?

дивні у вас питання, якщо мова про виндовс , то подивіться PEB та TEB структури. Можливо там буде те що вас цікавить.

14

Re: Як визначити скільки памяті займає об'єкт?

Якщо вже на те пішло, то таблиці символів можуть бути збережені окремо і використовуватися при зневадженні.
Але, звісно, програма чудово працює і без цих таблиць.

15

Re: Як визначити скільки памяті займає об'єкт?

Так, додатково погугливши і краще розібравшись у питання мені стало все більш-менш зрозуміло.
Всім дякую за відповіді.
cheappi386, чому дивні? Про PEB та TEB подивлюся, дякую.