Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
 Аватар для Lyosha12
41 / 41 / 11
Регистрация: 02.04.2016
Сообщений: 313

Почему нельзя выделить статически кусок в ~100 MB?

25.11.2016, 20:19. Показов 2802. Ответов 42
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть код
Кликните здесь для просмотра всего текста
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
37
38
39
40
#include <iostream>
using namespace std;
enum {
    length = 256,
    count = 50
};
struct Town {
    char name[length] = {};
 
    int nStadium;
    struct {
        char type[length] = {};
        char track[length] = {};
        int nGames;
        char games[count][length] = {};
        int capacity;
    } stadiums[count];
 
    int nPool;
    struct {
        int size;
        int nGames;
        char games[count][length] = {};
    } pools[count];
 
    int nGym;
    struct {
        char type[length];
        int nGames;
        char games[count][length] = {};
    } gyms[count];
};
 
int main() {
    int nTowns;
    Town towns[count];
 
    cout << sizeof(towns);
    return 0;
}


При попытке запустить программу в дебаге, среда ловит ошибку сегментации, на функции main (CLion, MinGW, Windows 7).

Объясните пожалуйста, почему, при наличии 4 GB памяти, это происходит? Неужели память настолько фрагментирована, что целого куска в 100 MB не найдётся (один объект весит ~2 MB)?

Если действительно настолько память фрагментирована, то что можно сделать? (Кроме динамического распределения, его я ещё на рассматриваю).
Миниатюры
Почему нельзя выделить статически кусок в ~100 MB?  
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
25.11.2016, 20:19
Ответы с готовыми решениями:

Почему нельзя банально выделить текст в паскале?
Почему нельзя банально выделить текст в паскале?

Как выделить кусок от символьного поля?
Здравствуйте, помогите, пожалуйста с проблемой: в ячейке А1 есть надпись , например &quot;поле 411&quot; Как выделить отсюда номер...

Выделить жирным кусок текста в MsWord.
Вообщем создаю таблицу в MsWord 2007. Дальше записываю в её ячейку текст. Так вот часть этого текста должна быть жирная, а другая...

42
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
27.11.2016, 15:26
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от alex white Посмотреть сообщение
локальная переменная, являющаяся указателем в кучу - это адрес, по которому хранится адрес значения.
С чего бы?
Локальная переменная, являющаяся указателем - это адрес, по которому лежит значение, а не адрес адреса.
Вот пример того, что сгенерировал компилятор:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
;
; Foo.method()
; Foo - локальный (стековый) объект.
;
lea     ecx,[ebp-1]
call    foo::method
 
;
; pFoo->method()
; pFoo - указатель на foo, выделенный в куче.
;
mov     ecx,dword ptr [ebp-4]
call    foo::method
Как видно по коду, уровень косвенности в обоих случаях одинаковый.

А вообще, всё это предположения о работе компилятора и внутренних
деталях реализации, на которые вряд ли стоит закладываться.
0
 Аватар для Lyosha12
41 / 41 / 11
Регистрация: 02.04.2016
Сообщений: 313
27.11.2016, 15:47  [ТС]
Цитата Сообщение от Убежденный Посмотреть сообщение
А вообще, всё это предположения о работе компилятора и внутренних
деталях реализации, на которые вряд ли стоит закладываться.
Это стоит сделать хотя бы раз, чтобы потом к этому, возможно, вернуться легко и непринуждённо. Что там делает компилятор с кодом - да, полностью забота его разработчиков. Мне же интересны хоть какие-то простые подробности этой деятельности.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
27.11.2016, 16:51
Цитата Сообщение от Убежденный Посмотреть сообщение
А память под стек что, из воздуха берется? Ее точно также выделяет диспетчер памяти,
только происходит это в другое время (при запуске программы или потока).
Не так. Под стек выделяется только адресное пространство. Реальное выделение памяти происходит при первом обращении к "сторожевой странице"/guard page. После этого к стеку прицепляется еще одна страничка, а guard page сдвигается. И так как такой механизм выдает одну страницу реальной памяти за раз, выделение больших (больше четырех кило) кусков данных будет происходить медленно и печально.

Впрочем, если брать микроконтроллеры и прочий Dos, то там таких заморочек скорее всего нет.
1
277 / 226 / 93
Регистрация: 27.06.2016
Сообщений: 639
27.11.2016, 17:09
Убежденный, имеется в виду адрес значения в куче. И приведённый ассемблерный код это подтверждает.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
27.11.2016, 21:21
Цитата Сообщение от Renji Посмотреть сообщение
Не так. Под стек выделяется только адресное пространство.
Хм. А разве может быть по-другому?

Реальное выделение памяти происходит при первом обращении к "сторожевой странице"/guard page. После этого к стеку прицепляется еще одна страничка, а guard page сдвигается. И так как такой механизм выдает одну страницу реальной памяти за раз, выделение больших (больше четырех кило) кусков данных будет происходить медленно и печально.
Да, согласен. Про guard page упустили момент.
Ну если уже идти дальше, то есть stack commit size, который никто не запрещает
сразу задать нужного размера.

Кстати, с памятью в куче ведь тоже в этом плане не все гладко.
Например, никто не гарантирует, что нужные страницы памяти сразу окажутся
загруженными в оперативку. И тогда получим массовые page fault-ы при
обращении к выделенному блоку.

Цитата Сообщение от alex white Посмотреть сообщение
Убежденный, имеется в виду адрес значения в куче. И приведённый ассемблерный код это подтверждает.
И что он подтверждает?
В первом случае объект лежит на стеке и обращение к нему происходит
через разыменование указателя - lea. Во втором случае объект лежит в
динамической памяти и обращаются к нему через mov dword ptr.
В обоих случаях уровень косвенности одинаковый.

Лично я такого не видел, чтобы локальная переменная - указатель
была реализована как указатель на указатель на данные...
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
27.11.2016, 21:54
Цитата Сообщение от Убежденный Посмотреть сообщение
Хм. А разве может быть по-другому?
Конечно. Можно не только выделить диапазон адресов ведущих в никуда, но и связать их с физической памятью/свопом. В реальном режиме других вариантов и не было.
Цитата Сообщение от Убежденный Посмотреть сообщение
Кстати, с памятью в куче ведь тоже в этом плане не все гладко.
Например, никто не гарантирует, что нужные страницы памяти сразу окажутся
загруженными в оперативку.
Если вы про overcommit, его вроде как отключить можно. Хотя да, по умолчанию никто доступности "выделенной" памяти не гарантирует.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
27.11.2016, 22:04
Цитата Сообщение от Renji Посмотреть сообщение
Можно не только выделить диапазон адресов ведущих в никуда, но и связать их с физической памятью/свопом.
Что-то я не улавливаю смысла написанного.
Как можно выделить память, ведущую в никуда?
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
27.11.2016, 22:16
Цитата Сообщение от Убежденный Посмотреть сообщение
Что-то я не улавливаю смысла написанного.
Как можно выделить память, ведущую в никуда?
Очень просто. При страничной организации памяти, приложение использует виртуальные адреса. Процессор транслирует эти адреса в физические, опираясь на записи в таблице страниц. Но в таблицу страниц мы можем записать и "да нет здесь ничего". Тогда получается что сами адреса вроде как приложению выделены, но фактически ведут в никуда. Технология overcommit как раз на таких потемкинских деревнях и держится.
1
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
27.11.2016, 22:26
Цитата Сообщение от Renji Посмотреть сообщение
...Но в таблицу страниц мы можем записать и "да нет здесь ничего"...
А, ты об этом... Ну так для прикладных задач таблицы страниц править никто не будет
(если мы все еще в русле современных популярных ОС, которые работают в защищенном режиме),
проще добиться примерно того же эффекта, используя зарезервированные страницы, т.е.
адреса-то выданы, но физическая память для них не выделена.

Но вообще да, в таких "щепетильных" темах лучше явно везде указывать, где
речь идет о виртуальной памяти, где о физической, и т.д.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
27.11.2016, 22:36
Цитата Сообщение от Убежденный Посмотреть сообщение
А, ты об этом... Ну так для прикладных задач таблицы страниц править никто не будет
(если мы все еще в русле современных популярных ОС, которые работают в защищенном режиме),
А VirtualProtect тогда что правит? Нет, прямого то доступа в подобной служебной информации никто не даст, но через API вызовы - всегда пожалуйста.
Цитата Сообщение от Убежденный Посмотреть сообщение
проще добиться примерно того же эффекта, используя зарезервированные страницы, т.е.
адреса-то выданы, но физическая память для них не выделена.
Так откуда эти страницы берутся, если не из шаманств с таблицей страниц?
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
27.11.2016, 22:51
Renji, наверное, я неправильно истолковал понятие "память, ведущая в никуда".
Если ты подразумеваешь под этим память, к которой нет доступа (PAGE_NOACCESS) или
память, которая зарезервирована, но не обеспечена физически, тогда тут все понятно и
нет предмета спора, а все мои сообщения, начиная с #25, можно смело зачеркивать (за
исключением того, что адресовано alex white по поводу косвенности).

Мне почудилось, что "память, ведущая в никуда" - это нечто другое.
Возможно, что-то слегка мистическое
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
27.11.2016, 22:52
Цитата Сообщение от Убежденный Посмотреть сообщение
Если ты подразумеваешь под этим память, к которой нет доступа (PAGE_NOACCESS) или
память, которая зарезервирована, но не обеспечена физически, тогда тут все понятно и
нет предмета спора
Да, я говорил про память не обеспеченную физически. Видимо, действительно друг друга не поняли.
0
277 / 226 / 93
Регистрация: 27.06.2016
Сообщений: 639
28.11.2016, 00:05
Убежденный, первый адрес - есть адрес локальный переменной. Второй адрес - адрес в куче. В первом случае, нам достаточно для работы со значением пройти по первому адресу, во втором - сначала добраться до локальной переменной (первый адрес), затем пройти по адресу, который хранится в ней. Что непонятного?
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,875
28.11.2016, 00:20
Цитата Сообщение от alex white Посмотреть сообщение
Второй адрес - адрес в куче. В первом случае, нам достаточно для работы со значением пройти по первому адресу, во втором - сначала добраться до локальной переменной (первый адрес), затем пройти по адресу, который хранится в ней.
mov и lea выполняются за одно и тоже время, один такт
0
277 / 226 / 93
Регистрация: 27.06.2016
Сообщений: 639
28.11.2016, 00:26
ValeryS, ну и пусть, не одним интелом живем, в любом случае косвенность дополнительная есть.
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,875
28.11.2016, 00:32
Цитата Сообщение от alex white Посмотреть сообщение
в любом случае косвенность дополнительная есть.
и что?
Цитата Сообщение от alex white Посмотреть сообщение
не одним интелом живем,
и АВРок и АРМов косвенная адресация неплохо развита
0
277 / 226 / 93
Регистрация: 27.06.2016
Сообщений: 639
28.11.2016, 00:35
ValeryS,
и что?
изначально именно с этим здесь начали спорить.
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,875
28.11.2016, 00:37
Цитата Сообщение от alex white Посмотреть сообщение
изначально именно с этим здесь начали спорить.
не с этим а с тем, что обращение к куче будет медленней
как показалУбежденный, затраты одни и те же
0
277 / 226 / 93
Регистрация: 27.06.2016
Сообщений: 639
28.11.2016, 00:41
ValeryS, давайте ещё будем спорить, о чем спорили.
Локальная переменная, являющаяся указателем - это адрес, по которому лежит значение, а не адрес адреса.
Как видно по коду, уровень косвенности в обоих случаях одинаковый.
Как видно, придирался Убежденный как раз к утверждению о косвенности, а про скорость речи практически не заходило. Расходимся.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
28.11.2016, 09:27
Цитата Сообщение от alex white Посмотреть сообщение
Как видно, придирался Убежденный как раз к утверждению о косвенности
Придирался - это слишком сильно сказано.
Скорее, пытался ставить под сомнение категоричность некоторых высказываний

Ок. Рассмотрим простой код:
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
37
#include <new>
#include <cstdio>
 
struct foo
{
    void method()
    {
        printf("%d, %d\r\n", val1, val2);
    }
 
    int val1;
    int val2;
};
 
void TestStack()
{
    foo Foo;
    Foo.val1 = 123;
    Foo.val2 = 456;
    Foo.method();
}
 
void TestHeap()
{
    foo * pFoo = new foo();
    pFoo->val1 = 123;
    pFoo->val2 = 456;
    pFoo->method();
    delete pFoo;
}
 
int main()
{
    TestStack();
    TestHeap();
    return 0;
}
Вот сгенерированный компилятором ассемблерный листинг функций TestStack и
TestHeap соответственно (все лишнее повырезано):
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
;
; TestStack
;
 
; ...
01291037 c745f87b000000  mov     dword ptr [ebp-8],7Bh
0129103e c745fcc8010000  mov     dword ptr [ebp-4],1C8h
01291045 8d4df8          lea     ecx,[ebp-8]
01291048 e8b3ffffff      call    foo::method (01291000)
; ...
 
;
; TestHeap
;
 
; ...
012910ad c7027b000000    mov     dword ptr [edx],7Bh
012910b6 c74004c8010000  mov     dword ptr [eax+4],1C8h
012910bd 8b4dfc          mov     ecx,dword ptr [ebp-4]
012910c0 e83bffffff      call    foo::method (01291000)
; ...
В TestStack объект foo находится в стеке по адресу 'ebp-4'. В TestHeap в стеке по адресу
'ebp-8' лежит адрес foo, выделенного в куче. Подчеркиваю: адрес foo, а не адрес адреса foo.
Это противоречит твоему утверждению, что "локальная переменная, являющаяся указателем в кучу -
это адрес, по которому хранится адрес значения". Как видно по листингу, такая переменная -
это и есть адрес объекта, а не адрес адреса. В ecx в обоих случаях загружается адрес foo.

Именно это утверждение про адрес адреса я и ставлю под сомнение.

В листинге также видно, что работа с объектом (установка членов и вызов метода) приводят к
генерации идентичного кода, где лишней косвенности нет, за исключением взятия адреса объекта.

-----------------------------------------------------------------------------------------------

Все это было написано исключительно с целью показать, что закладываться на такие детали
генерации кода нельзя, что работа с объектом через указатель - это не всегда дополнительный
уровень косвенности, и что в реальном проекте оптимизация и другие специфические условия
могут изменить конечный ассемблерный код до неузнаваемости.
4
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
28.11.2016, 09:27

В верстке совместимо с бутстрапом выделить большой кусок текста
Всем привет, Подскажите, пожалуйста, как можно в верстке совместимо с бутстрапом выделить большой кусок текста... Хочется слева от...

Почему нельзя командой copy скопировать системные файлы на дискету? Почему?
Пожалуйсат, подскажите, весь интернет перерыла, вот почему нельзя? что нельзя знаю, а по какой причине?

На рабочем столе нельзя перетаскивать ярлыки, нельзя копировать файлы и нельзя их вставлять
После загрузки компьютера вылезла ошибка, что кокойто файл windows неможет прочесть было предложено открыть программу CHKDSK, после этого ...

Почему не работает этот кусок программы?
Дана цепочка 00000101001010 она записана в массив, каждая цифра отдельный элемент. нужно инвертировать, не используя специальных...

Почему 100.6 - Int(100.6) = 0.59999999999999432
100.6 - Int(100.6) = 0.59999999999999432 Ну ведь не должно так быть?! 100.6 - Math.Floor(100.6) дает тот же результат.


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Doom для терминала без стрельбы и монстров. 3D Raycasting на ascii.
dcc0 05.07.2026
Попросил нейронную сеть deepai. org написать рейкастинг 3D с библиотекой ncurses для Linux. Чтобы можно было ходить на стрелочки. Чтобы стены были отрисованы символами. Справилась. Первый вариант. . .
Установка статуса документа по условию
Maks 05.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "НарядПутевка" разработанного в КА2. Задача: в табличной части "Материалы" документа при записи автоматически устанавливать статус. . .
Сезонность и суточность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет. Но обычно это 50 лет и более. Наверное, закисление почвы происходит сезонно в средней. . .
В чем ценность человеческого опыта в глобальном смысле?
kumehtar 03.07.2026
Возможно, ценность человека не в том, что он однажды достигает мудрости, а в том, что он становится носителем карты пути. Он знает не только истину, но и последовательность внутренних изменений,. . .
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
Поиск всех путей на ориентированном графе. Linux
dcc0 02.07.2026
Переработка старого кода из моей статьи. Через несколько переработок от PHP кода к C89 (надеюсь, 89). Но довольно запутанно получилось. Код для Linux. Но если убрать time и то, что с ним. . .
Сам себя обучал rest api
anaschu 02.07.2026
Педагогический лайфхак: Почему чистый REST API для ученика намного круче, чем готовые библиотеки Когда мы отказались от капризного JAR-файла AnyLogic и переписали код на стандартный HttpClient,. . .
rest api anylogic - выполнение модели на своём русском сайте
anaschu 02.07.2026
Как подружиться с AnyLogic Cloud API, победить провайдеров и развернуться Java-бэкенд в Docker на бесплатном хостинге: Двухдневный лог борьбы Всем привет! Хочу поделиться свежим (и довольно. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru