Тема: Як визначити скільки памяті займає об'єкт?
Я знаю, що є оператор sizeof, але мене цікавить, чи можна написати свій аналог?
Тобто, чи можна десь подивитися на реалізацію sizeof, ну, чи на те, як він працює?
Ви не увійшли. Будь ласка, увійдіть або зареєструйтесь.
Ласкаво просимо вас на україномовний форум з програмування, веб-дизайну, SEO та всього пов'язаного з інтернетом та комп'ютерами.
Будемо вдячні, якщо ви поділитись посиланням на Replace.org.ua на інших ресурсах.
Для того щоб створювати теми та надсилати повідомлення вам потрібно Зареєструватись.
Український форум програмістів → C++ → Як визначити скільки памяті займає об'єкт?
Сторінки 1
Для відправлення відповіді ви повинні увійти або зареєструватися
Я знаю, що є оператор sizeof, але мене цікавить, чи можна написати свій аналог?
Тобто, чи можна десь подивитися на реалізацію sizeof, ну, чи на те, як він працює?
Можете пояснити, що саме ви збираєтеся робити? Можете навести приклад коду, в якому вам потрібен цей аналог замість звичайного sizeof?
Реалізацію можете подивитися у вихідному коді компілятора, але навіщо? Що саме не зрозуміло з його роботою?
sizeof насправді вбудований досить глибоко в структуру мови. C++ активно покладається на арифметику вказівників, і неможливо знайти наступний елемент масиву без sizeof. Нащо його змінювати чи перевизначати?
Ну, як я зрозумів sizeof працює лише в момент компіляції, а якщо я допустимо хочу дізнатися розмір під час виконання?
Не зовсім зрозуміло, як він реалізований всередині? Тобто є якісь дескрайбери для об'єктів?
Я не збираюся замінювати вбудований sizeof, а просто мати свою версію в додаток, не більше.
Я знаю, що є оператор sizeof, але мене цікавить, чи можна написати свій аналог?
В загальному випадку - ні.
Тобто, чи можна десь подивитися на реалізацію sizeof, ну, чи на те, як він працює?
Подивитися, напевно, так, як ви собі уявили не можна.
Ну, як я зрозумів sizeof працює лише в момент компіляції, а якщо я допустимо хочу дізнатися розмір під час виконання?
Ем, що?
В статично типізованій мові не буває об'єкта без типу, а раз так, то достатньо знати розміру типу на етапі компіляції.
Якщо у вас об'єкт невідомого типу, і ви посилаєтеся на нього, наприклад через void-вказівник, то ніяк ви його розмір не визначите.
Не зовсім зрозуміло, як він реалізований всередині? Тобто є якісь дескрайбери для об'єктів?
Який "дескрайбер"? Навіщо?
"Класичний" sizeof - конструкція часу компіляції. Компілятор знає розмір кожного типу. Звідси sizeof і знає, "скільки пам'яті займає об'єкт". Компілятор знає, що тип int має розмір 4. Тому sizeof(int) дає 4.
Все доволі просто.
Ага. Ну, все одно sizeof читає ім'я змінної і навіть в момент компіляції потрібно знати інформацію про об'єкт, значить вона ж десь записана ця інформація, чи ви хочете сказати що в момент компіляції відбувається пошук слова int?
Ага. Ну, все одно sizeof читає ім'я змінної і навіть в момент компіляції потрібно знати інформацію про об'єкт, значить вона ж десь записана ця інформація, чи ви хочете сказати що в момент компіляції відбувається пошук слова int?
Ні, під час компіляції складається таблиця символів програми, і там записано, що такий-то ідентифікатор - це int, а int має фіксований розмір.
а якщо я допустимо хочу дізнатися розмір під час виконання?
А яким чином, вибачте, ви можете отримати розмір змінної під час виконання не таким, як під час компіляції?
От, власне, чому програмістам треба хоча б базове уявлення про асемблер мати - тоді такі питання просто не виникають.
Ну, власне, є єдина ситуація, коли можна таки не знати розміру змінної під час компіляції - це виділення масиву у купі (new []). Тоді в службовій інформації купи зберігається, який розмір виділено, і до цього розміру в програміста немає доступу, треба десь окремо запам'ятовувати, є таке. Але досі це нікому суттєвих проблем не створювало.
mimik, що саме намагаєтесь зробити? Приведіть шматочок коду для прикладу, бо геть не зрозуміло що потрібно зробити.
koala, дякую, загалом все зрозуміло.
Але ж наприклад під час роботи програми вже немає ніяких таблиць?
Але ж наприклад під час роботи програми вже немає ніяких таблиць?
Все вірно, ніяких таблиць з інформацією про розміри типів на етапі виконання не існує. На етапі виконання вже всюди фігурують тільки константи дбайливо підставлені компілятором в усі потрібні інструкції на етапі компіляції.
Мова для того і існує щоб компілятор коректно перетворив бажання програміста в машинний код(інструкції).
Уточню, бо це вочевидь потрібно. Інструменти нагуглив у два запити, можливо, є й зручніші.
Отже, процесор виконує байт-код. Приклад можете глянути тут: 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 і переконатися, що в асемблері там буде число, а не операція.
koala, дякую, загалом все зрозуміло.
Але ж наприклад під час роботи програми вже немає ніяких таблиць?
дивні у вас питання, якщо мова про виндовс , то подивіться PEB та TEB структури. Можливо там буде те що вас цікавить.
Якщо вже на те пішло, то таблиці символів можуть бути збережені окремо і використовуватися при зневадженні.
Але, звісно, програма чудово працює і без цих таблиць.
Так, додатково погугливши і краще розібравшись у питання мені стало все більш-менш зрозуміло.
Всім дякую за відповіді.
cheappi386, чому дивні? Про PEB та TEB подивлюся, дякую.
Сторінки 1
Для відправлення відповіді ви повинні увійти або зареєструватися