Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.70/40: Рейтинг темы: голосов - 40, средняя оценка - 4.70
0 / 0 / 0
Регистрация: 12.03.2012
Сообщений: 7

Выделение памяти под int

10.02.2015, 18:46. Показов 7408. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день!!

Недавно начал разбираться с С#. Есть теоретический вопрос:

int (System.Int32) в памяти занимает 4 байта, ровно столько, сколько выделено под само число. Как такое может быть? Ведь это структура. Как это реализовано?

Спасибо.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
10.02.2015, 18:46
Ответы с готовыми решениями:

Выделение памяти под объект в нужное время
Задумался тут, а зачем нужно выделять память сразу под все объекты, которые будут использоваться, а не тогда когда это необходимо? ...

Разработать таблицу имен, обеспечивающую динамическое выделение памяти под имена
разработать таблицу имен, обеспечивающую динамическое выделение памяти под имена по мере надобности. Таблица должна быть построена на...

Разработать таблицу имен, обеспечивающую динамическое выделение памяти под имена по мере надобности
Разработать таблицу имен, обеспечивающую динамическое выделение памяти под имена по мере надобности. Таблица должна быть построена на...

16
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
10.02.2015, 18:57
Цитата Сообщение от russov Посмотреть сообщение
Как такое может быть?
А сколько должно? Это не класс, нет дополнительных членов (индекс блока синхронизации и т.д), поэтому и занимает именно столько.
Цитата Сообщение от russov Посмотреть сообщение
Как это реализовано?
Посмотрите исходный код данной структуры.
0
0 / 0 / 0
Регистрация: 12.03.2012
Сообщений: 7
11.02.2015, 08:49  [ТС]
Память должна выделяться как минимум под "MaxValue" и "MinValue" по 4 байта для каждого.

Cтруктура Int32:

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
29
30
31
32
33
34
35
36
public struct Int32 : IComparable, IFormattable, IConvertible, IComparable<int>, IEquatable<int>
    {
        public const int MaxValue = 2147483647;
        public const int MinValue = -2147483648;
        [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
        public int CompareTo(int value);
        public int CompareTo(object value);
        [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
        public bool Equals(int obj);
        [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
        public override bool Equals(object obj);
        [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
        public override int GetHashCode();
        [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
        public TypeCode GetTypeCode();
        public static int Parse(string s);
        [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
        public static int Parse(string s, IFormatProvider provider);
        public static int Parse(string s, NumberStyles style);
        [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
        public static int Parse(string s, NumberStyles style, IFormatProvider provider);
        [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
        [SecuritySafeCritical]
        public override string ToString();
        [SecuritySafeCritical]
        [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
        public string ToString(IFormatProvider provider);
        [SecuritySafeCritical]
        [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
        public string ToString(string format);
        [SecuritySafeCritical]
        public string ToString(string format, IFormatProvider provider);
        public static bool TryParse(string s, out int result);
        [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
        public static bool TryParse(string s, NumberStyles style, IFormatProvider provider, out int result);
    }
0
foo();
 Аватар для rattrapper
886 / 587 / 222
Регистрация: 03.07.2013
Сообщений: 1,549
Записей в блоге: 2
11.02.2015, 09:17
russov, min и max не зависят от экземпляра. Т.е. они не хранятся в каждой переменной типа int
0
0 / 0 / 0
Регистрация: 12.03.2012
Сообщений: 7
11.02.2015, 11:16  [ТС]
Но если я создам свою такую же структуру "Int32_My" например, такой объект никак не 4 байта будет занимать. Пологаю здесь присутствует не сстандартное поведения для объектов стандартных типов. Возможно я не прав, если кто-то может, объясните на пальцах, как так получается. Большое спасибо.

min и max - они не статические, почему они не хранятся в каждой переменной.
0
Неадекват
 Аватар для freeba
1499 / 1236 / 247
Регистрация: 02.04.2010
Сообщений: 2,807
11.02.2015, 11:46
russov, int - будет занимать в памяти ровно 4 байта. Для этого надо совершить экскурс во внутреннее устройство типов - это уровень объемной статьи, но если кратко:

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

Соответственно если для ссылочного типа указатель на экземпляр - это указатель на таблицу методов объекта, то указатель на тип значения - это указатель на само значение, или на первое значение если речь о структуре с несколькими полями.

Перефразируя товарища Сталина - не важно как написано, важно во что скомпилировалось.
3
 Аватар для Cupko
654 / 591 / 171
Регистрация: 17.07.2012
Сообщений: 1,680
Записей в блоге: 1
11.02.2015, 13:40
Цитата Сообщение от freeba Посмотреть сообщение
если структура имеет методы, она превращается в ссылочный тип с точки зрения представления в памяти
Поясните, пожалуйста. Откуда информация.

Я далеко не гуру в управлении памятью в .Net, но данное утверждение меня смутило.
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
11.02.2015, 14:03
Цитата Сообщение от Cupko Посмотреть сообщение
Поясните, пожалуйста. Откуда информация.
Поддерживаю. Тоже хотелось бы знать.
Цитата Сообщение от freeba Посмотреть сообщение
превращается в ссылочный тип с точки зрения представления в памяти
То есть, если так, то мы не сможем получить на нее указатель (она же будет в куче, если я правильно понимаю).
Но вот такой код компилируется и выполняется... Или я что-то не так понял?
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
29
30
31
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace STRUCT_Test {
    unsafe class Program {
        static void Main(string[] args) {
            TEST_1 t1 = new TEST_1();
            TEST_2 t2 = new TEST_2();
 
            TEST_1* t1Ptr = &t1;
            TEST_2* t2Ptr = &t2;
 
            t1Ptr->X = 10;
            t2Ptr->X = 20;
 
            Console.WriteLine("t1Ptr address: {0:X}, t1Ptr X value: {1}", (int)(t1Ptr), t1Ptr->X);
            Console.WriteLine("t2Ptr address: {0:X}, t2Ptr X value: {1}", (int)(t2Ptr), t2Ptr->X);
            Console.ReadLine();
        }
    }
    struct TEST_1 {
        public int X;
    }
    struct TEST_2 {
        public int X;
        public void Method() {
        }
    }
}
0
Неадекват
 Аватар для freeba
1499 / 1236 / 247
Регистрация: 02.04.2010
Сообщений: 2,807
11.02.2015, 14:27
Цитата Сообщение от Cupko Посмотреть сообщение
Я далеко не гуру в управлении памятью в .Net, но данное утверждение меня смутило.
Цитата Сообщение от insite2012 Посмотреть сообщение
то мы не сможем получить на нее указатель (она же будет в куче, если я правильно понимаю).
Сможем. Типы значений не могут содержать методы, однако в шарпе мы можем добавить в структуру метод - получается некоторое несоответствие, таблица методов не предусмотрена, а методы есть. В этом случае структура будет упакована в ссылочный тип, при чем упакованная версия никак не связана с оригиналом и какая именно версия будет использоваться решает компилятор.

Во вложении иллюстрация размещения структур в памяти без методов и с методами.

PS: Информация из книги "Оптимизация приложений на платформе .NET"
Миниатюры
Выделение памяти под int  
2
 Аватар для Cupko
654 / 591 / 171
Регистрация: 17.07.2012
Сообщений: 1,680
Записей в блоге: 1
11.02.2015, 14:35
freeba, Эм...
Не таблица методов не предусмотрена, а указатель на таблицу методов не предусмотрен. Он и не нужен для структур.

Сам указатель на таблицу методов внутри объекта нужен для динамического полиморфизма (...и ещё Б-г знает для чего). Так как структуры - тип закрытый для наследования, этот указатель не нужен. Единственное исключение, это даункастинг к Object и к интерфейсу, но тут в CLR есть замечательный костыль в виде boxing/unboxing.

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

Прошу поправить меня, где я не прав.
2
Неадекват
 Аватар для freeba
1499 / 1236 / 247
Регистрация: 02.04.2010
Сообщений: 2,807
11.02.2015, 14:55
Цитата Сообщение от Cupko Посмотреть сообщение
но тут в CLR есть замечательный костыль в виде boxing/unboxing.
Об этом костыле и речь. Если есть возможность обойтись без боксинга - будет использоваться оригинальная версия, в противном случае структура отправится в динамическую память в виде объекта.
0
 Аватар для Cupko
654 / 591 / 171
Регистрация: 17.07.2012
Сообщений: 1,680
Записей в блоге: 1
11.02.2015, 15:03
freeba, я понял, что вы о boxing/unboxing, я просто воспринял ваше
Цитата Сообщение от freeba Посмотреть сообщение
если структура имеет методы, она превращается в ссылочный тип с точки зрения представления в памяти
, как: "Любая структура имеющая методы будет расположена на куче". С чем я, собственно, и не согласен. Опровержения этого утверждения я так и не увидел. Вполне возможно, что тут присутствует некоторое недопонимание с моей стороны.
1
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
11.02.2015, 15:14
Цитата Сообщение от freeba Посмотреть сообщение
Типы значений не могут содержать методы, однако в шарпе мы можем добавить в структуру метод - получается некоторое несоответствие
В каком языке типы значений не могут содержать методы?
Применительно к шарпу несоответствия нет.

Цитата Сообщение от freeba Посмотреть сообщение
таблица методов не предусмотрена, а методы есть.
Таблица методов предусмотрена для структур и хранится она в информации о типе.
Тип используемой структуры известен статически, потому указатель на объект-тип, как в случае с классами, не нужен.

Цитата Сообщение от freeba Посмотреть сообщение
В этом случае структура будет упакована в ссылочный тип, при чем упакованная версия никак не связана с оригиналом и какая именно версия будет использоваться решает компилятор.
Это утверждение очень легко проверяется или опровергается обычной проверкой адреса поля структуры при вызове напрямую и при вызове из метода. Если адреса разные, то имеет место запаковка, если одинаковые, то нет.

Цитата Сообщение от freeba Посмотреть сообщение
Информация из книги "Оптимизация приложений на платформе .NET"
Иллюстрация показывает расположение структуры в куче в запакованном виде, но из этого не следует, что при вызове метода на структуре происходит запаковка.
Либо в книге ерунда написаны, либо вы что-то не так поняли.
2
Неадекват
 Аватар для freeba
1499 / 1236 / 247
Регистрация: 02.04.2010
Сообщений: 2,807
11.02.2015, 15:18
Cupko, Выразился несколько некорректно. Подразумевал что при операции упаковки структура будет занимать в памяти столько же сколько и ссылочный объект.

А так если структура состоит из двух полей типа int - она всегда будет занимать 8 байт вне зависимости от реализации.
1
 Аватар для Cupko
654 / 591 / 171
Регистрация: 17.07.2012
Сообщений: 1,680
Записей в блоге: 1
11.02.2015, 15:29
Цитата Сообщение от freeba Посмотреть сообщение
А так если структура состоит из двух полей типа int - она всегда будет занимать 8 байт вне зависимости от реализации.
Тут тоже спорно, или опять моё недопонимание
C#
1
2
3
4
5
6
[StructLayout(LayoutKind.Sequential, Size = 16)]
internal struct MyStruct
{
    private int a;
    private int b;
}
В общем, так или иначе, это не совсем относится к обсуждению.
0
11.02.2015, 16:25

Не по теме:

Цитата Сообщение от Cupko Посмотреть сообщение
Тут тоже спорно, или опять моё недопонимание
:D Небезопасный код не в счет.

К тому это выделение памяти под структуру, фактом все равно будет занято только 8 байт.

0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6101 / 4957 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
11.02.2015, 18:35
kolorotur, я читал эту книгу и тоже удивился, потому что не помнил там ничего подобного. Книжка кстати очень хорошая, называется "что будет, если выжать всю воду из рихтера + пара полезных советов". Я например оттуда узнал про __makeref и прочие недокументированные фичи шарпа, что позволяет работать с указателем на структуру <T> (там был пример про преобразованию набора байт в структуру методами шарпа, очень любопытный).
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
11.02.2015, 18:35
Помогаю со студенческими работами здесь

Стек, куча, хранение в памяти, динамическое выделение памяти, указатели в чем отличие?
Здравствуйте. Прочитал кучу определений но никак не пойму вообще что к чему. 1)Стек - это якобы кусок оперативной памяти который...

Выделение памяти
Интересует вот такой вопрос: можно ли в шарпе выделить определённый объём памяти, скажем 100 мб? Если да, то как? А вообще я хочу...

Выделение неуправляемой памяти
Всем привет! По незнанию скопипастил код в котором было использовано вот такое выделение неуправляемой памяти var headerPtr =...

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

Выделение/освобождение памяти
помогите пожалуйста, в С++ есть конструкции вида xx=AllocMemInt2D(LL, NN); DeAllocMemFloat2D(LL, x); которые выделяют и освобождают...


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
PowerShell Snippets
iNNOKENTIY21 11.11.2025
Модуль PowerShell 5. 1+ : Snippets. psm1 У меня модуль расположен в пользовательской папке модулей, по умолчанию: \Documents\WindowsPowerShell\Modules\Snippets\ А в самом низу файла-профиля. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru