Ну просто огромнейшее спасибо всем экспертам за ответы про динамические массивы (вопрос 890). Про организацию этих самых массивов в памяти я даже и не думал. Поэтому задам ещё один вопрос (только для удовлетворения собственного любопытства): если мы используем двумерный динамический массив, то в памяти должны храниться указатели на начала столбцов этого массива? Если так, то допустим, что мы изменяем длину, скажем, второго столбца и делаем её очень большой (очень, очень большой). При линейной организации адресации памяти программа должна будет изменить адрес этого столбца? Это и есть фрагментация памяти по Бобу Джонсону :)? Пуху пух, миру мир. Алексей.
Приветствую Вас, Алексей! > Это и есть фрагментация памяти по Бобу Джонсону :)? Ну пока еще фрагментацию памяти не назвали моим именем :) Минимальной гибкой единицой измерения памяти с точки зрения процессора является страница (4кб). Процессор, за счет страничного преобразования может изменять физическое положение логического адреса, но блоками по 4 к. При этом, пока мы работаем со страницами, хоть и возникает из физическая фрагментация, на скорость работы программы это влияет не сильно. Но немного влияет, т.к. логически непрерывный блок памяти становится физически прерывным и операции с ним в целом будут идти несколько медленнее, т.к. современная память заточена именно под линейные операции. Но, к сожалению, блоками по 4 к раздавать память не всегда удобно, т.к. это достаточно большой объем. Поэтому ОС организовывает свою структуру памяти. В дос это
был MCB (Memory Control Block), в Windows - что-то еще. При этом общая тактика этого процесса проста - у каждого куска памяти есть свой заголовок, который хранит длину и состояние (свободен/занят) этого куска. За ним находится следующий кусок и т.д. При этом, если освобождается кусок памяти и с одной из его сторон есть уже свободный, они объединяются. Когда же ты выделяешь себе память, ОС (или какой-либо Memory Manager) пробегает свободные блоки и находит подходящий по объему. Если его объем несколько больше, то он делится на два блока, первый отдается тебе, второй помечается как свободный. Вот такое дробление памяти и есть фрагментация. Чем она плоха - при выделении памяти MM должен вначале просмотреть свободные блоки, что может занимать время. Также небольшие свободные участки просто занимают место, но могут быть никогда не выделены из-за их малого объема. Насколько я знаю, механизмов
дефрагментации памяти в Windows нет, т.е. это можно сделать только отдав назад абсолютно всю выделенную память. Также, если ты будешь выделять себе маленький участок памяти, а затем увеличивать его по мере необходимости (но это будет часто), то начнут возникать ситуации, когда ММ не хватит текущего блока (а следующий будет уже занят) и он будет вынужден перенести данные из него в другой блок подходящего размера, что уже медленно. Поэтому осуществи определенного рода "кэширование" - выдели вначале себе блок не минимально возможной длины, а средней, которая будет оптимальна с точки зрения и объема ОП, и своего размера. Это позволит тебе избежать некоторых операций изменения размера блока и твоя программа будет работать несколько быстрее. > При линейной организации адресации памяти программа должна будет изменить адрес этого столбца? Вполне возможно.
* EMan1.5: ---===*** The game we play ***===---
Ответ отправлен: 06.09.2003, 22:17 Отправитель: Bob Johnson Отвечает --- Нет данных ---
Приветствую Вас, Алексей! Очень сильно зависит от метода организации двумерного массива. Можно делать как-бы эмуляцию его одномерным, а можно сделать массив указателей на массивы (у Вас похоже второй вариант), и тогда память будет действительно вот так вот хитро фрагментироватся (т.е. столбец даже возможно будет хранится в памяти не подряд).
Приложение: Ответ отправлен: 09.09.2003, 17:36 Отправитель: --- Нет данных ---
Вопрос № 901
Как загрузить в StringGrid графический файл? Здравствуйте, ув. эксперты. Никогда не работал с графикой в Delphi, требуется помощь. Нужно в ячейку StringGrid'а загрузить значок. Делаю примерно так: var ... rec : TRect; graph : TPicture; begin graph.LoadFromFile('C:Horse.ico'); ... for RC := 1 to RowCount-1 do // Cells[RC+4, RC] := 'X'; begin rec := CellRect(RC+4,RC); Canvas.StretchDraw(rec,graph.Graphic); end; ... Смысл - заполнение диагональных клеток шахматной таблицы не крестиками, а изображением коня. Ошибка возникает при загрузке файла (LoadFrom...), дальше тоже наверно есть, пока не знаю. Ясно, что что-то не так, но в моей литературе работа с Canvas скупо описана. (Да, все делается со StringGrid: with ...) P.S. Поздравляю Боба Джонсона с юбилеем.
Здравствуйте, Loko! Объект Graph надо создать вначале. Graph := TPicture.Create; Ответ отправлен: 08.09.2003, 09:51 Отправитель: Marouder
Вопрос № 902
К вопросу или 895, или 896 или 898 (там, где в приложении 3 маленькие процедурки). Плиз, киньте кто-нибудь эти процедурки мне назад - они у меня почему-то не сохранились.
Приложение: Ответ отправлен: 09.09.2003, 17:45 Отправитель: URiS
Вопрос № 903
Здравствуйте, эксперты. У меня вопрос: как мне при завершении работы моего приложения вернуть какой-нибудь код. Иными словами - код возврата из функции WinMain.
Здравствуйте, Eugene! Выходи с помощью ExitProcess (из обработчика OnClose формы вызови ExitProcess). Ответ отправлен: 08.09.2003, 09:54 Отправитель: Marouder Отвечает vitya
Доброе время суток, Eugene! там где вызываете PostQuitMessage(), вот параметр и есть возвращаемое значение.
Ответ отправлен: 08.09.2003, 08:46 Отправитель: vitya Отвечает Delphist
Здравствуйте, Eugene! В конце WinMain ставишь return (код возврата). Одна фигня Windows он по барабану, а вообще код нормального выхода - 0. Все остальное - выход если произошла ошибка. Ответ отправлен: 08.09.2003, 13:03 Отправитель: Delphist Отвечает Артём Шегеда
Доброе время суток, Eugene!
Для Delphi я бы в project1.dpr после строки Application.Run; добавил бы код: Halt(ExitCode); Ответ отправлен: 08.09.2003, 13:26 Отправитель: Артём Шегеда Отвечает Bob Johnson
Здравствуйте, Eugene! Если не найдешь ничего в VCL, используй ExitProcess (code). Только имей ввиду, что при этом осуществляется мгновенный выход, и все операции, которые обычно делает при этом VCL выполнены не будут. В принципе, глобальных проблем от этого не будет, т.к. сама ОС закрывает за процессом все хэндлы, память и т.д. Да, вот сейчас взглянул в основной файл проекта на билдере, там в конце есть "return 0" - вот это и есть код завершения. Посмотри, возможно в дельфи так же.
* EMan1.5: ---===*** The game we play ***===---
Ответ отправлен: 08.09.2003, 12:19 Отправитель: Bob Johnson Отвечает _vt
Приветствую Вас, Eugene! return число (это для билдера)
*** Updated E-Man 1.5 - it's cool! Join to us, if you're a real rusfaq expert! :-()***
Ответ отправлен: 08.09.2003, 23:11 Отправитель: _vt Отвечает URiS
Добрый день, Eugene! По-моему, это существовало только в DOS в виде Halt(code);
Ответ отправлен: 09.09.2003, 17:43 Отправитель: URiS Отвечает --- Нет данных ---
Добрый день, Eugene! return 15;непосредственно в WinMain (для возврата кода 15)
Ответ отправлен: 09.09.2003, 17:58 Отправитель: --- Нет данных ---
Форма отправки вопроса
Внимание!
Мы рекомендуем открывать рассылку в программе Internet Explorer 5.0+
или отправлять вопросы с сайта по адресу:
http://rusfaq.ru/cgi-bin/Message.cgi.