Форум программистов, компьютерный форум, киберфорум
Наши страницы
Delphi
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.56/108: Рейтинг темы: голосов - 108, средняя оценка - 4.56
Den_D
0 / 0 / 1
Регистрация: 15.02.2017
Сообщений: 3
1

Как работает SetLength()

24.09.2008, 15:06. Просмотров 19949. Ответов 8
Метки нет (Все метки)

Вопрос такой:
если у меня есть динамический массив dimass на n элементов я заполнил первые mэлементов нужной информацией, потом отсекаю осташиеся n-m элементов функцией SetLength(dimass, m). Может ли при этом случиться, что нужные мне данные с массива пропадут, т.е. указатель dimassпоменяет адрес.

Заранее спасибо за любые соображения.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.09.2008, 15:06
Ответы с готовыми решениями:

SetLength & EOutOfMemory
Столкнулся с такой проблемой, при заполнении динамического массива данными из...

Incompatible types в функции SetLength
Добрый вечер. У меня в программе есть собственная функция, где применяется...

Не работает Setlength для динамических массивов, если в параметрах процедуры стоят массивы на вход
Не работает Setlength для динамических массивов, если в параметрах процедуры...

Acess Violation из-за SetLength
Здравствуйте, хочу сделать что-то наподобии калькулятора, и столкнулся с одной...

SetLength. Access violation
Собственно при k=19 вылазит ошибка Access violation. Не могу понять почему: ...

8
Puporev
Модератор
56119 / 42980 / 29730
Регистрация: 18.05.2008
Сообщений: 102,009
24.09.2008, 15:17 2
Нет, первые m элементов сохранятся, а если уменьшив длину массива попробуете вывести данные на первоначальную длину, то интервал m+1 - n заполнится "мусором".
0
Den_D
0 / 0 / 1
Регистрация: 15.02.2017
Сообщений: 3
24.09.2008, 16:08 3
Вроде бы да, но когда речь идет в масштабах адресногоо пространства процесса 4 Гб, то неужели ОС не сделает релокацию памяти. Если я захочу увеличить размер массива, а начиная с ячейки памяти, на которую указывает dimass такого большого непрерывного блока незанятых адресов нету, но есть в другом месте адресного пространства процесса, то указатель массива поменяет адресс.
0
Turbosega
40 / 40 / 10
Регистрация: 27.06.2008
Сообщений: 118
24.09.2008, 16:15 4
Указатель не может поменять адрес если длина массива больше 0.
0
Den_D
0 / 0 / 1
Регистрация: 15.02.2017
Сообщений: 3
24.09.2008, 16:18 5
А если я уменьшу размер массива, то где гарантии, что оптимизатор не заткнет моим массивом какую-то дырку в адресном пространстве процесса, которая будет подходить по размеру, тем симым изменив адрес первого элемента массива. И где гарантии, что после этого оптимизатор скопирует все ячейки массива куда надо. Прошу прощения за сумбур.
0
Turbosega
40 / 40 / 10
Регистрация: 27.06.2008
Сообщений: 118
24.09.2008, 17:17 6
Насколько я поняв это все ты теоретически догадываешся! А ты пробовал делять всё это?
У тебя задача с видео повязана, что тебя надо так много байт массива?
0
Vovan-VE
13163 / 6549 / 1038
Регистрация: 10.01.2008
Сообщений: 15,070
24.09.2008, 18:57 7
У процессов своя локальная память, которая скорее всего находится в свопе. Чего гадать, берем и пробуем:
Код
var buffer:array of byte;
...
SetLength(buffer,$10000); // 64K
FillChar(buffer[0], $10000, $FF);
// смотрим значение адреса
Caption := 'было: 0x'+IntToHex(Integer(@buffer[0]),8);

// просим много памяти, пробовать очень много
SetLength(buffer,$1000000); //16M
FillChar(buffer[0], $1000000, $FF);
// смотрим еще раз значение адреса
Caption := Caption + '; стало = 0x'+IntToHex(Integer(@buffer[0]),8);
0
AlexKo
0 / 0 / 0
Регистрация: 03.10.2008
Сообщений: 3
03.10.2008, 16:39 8
Теоретически при изменении размера массива его начальный адрес может поменяться.
Практически же это произойдет только в случае увеличения его размера, если в данной области нет места под новый размер.
При уменьшении, менеджер памяти не будет перемещать данные, да и данные записанные в конце будут целыми, пока на их место не запишутся новые.

Но даже если адрес поменяется, то все данные переместятся в новое место. Т.е. заполнив первые 5 элементов и вызвав SetLength(DimMass, 5) можно быть на 100% уверенным что по DimMass[4] мы прочитаем то что записали туда раньше.

А вот так, лучше не писать. Хотя как я сказал выше, дрес при уменьшении не поменяется, но расчитывать на это не стоит, т.к. алгоритм работы менеджера памяти может поменяться.

Код
var PData: PInteger;
     DimMass: array of integer;

...........
SetLength(DimMass, 196);
PData:= @DimMass[0];

...........
SetLength(DimMass, 5);

//Возможно PData уже недействителен и лучше его проинициализировать заново

Show(PData); //Тут мы что-то сделаем с данными
P.S. А оптимизатор - это при компиляции, размещением данных занимается менеджер памяти.
0
Vovan-VE
13163 / 6549 / 1038
Регистрация: 10.01.2008
Сообщений: 15,070
03.10.2008, 18:35 9
Когда мы меняем размер массива, естественно мы учитываем вероятность смены адреса. А если нам точно не нужно изменение адреса, то мы просто не будем менять реальный размер, мы будем использовать столько, сколько хотим. Хотя жадничать тоже плохо.
0
03.10.2008, 18:35
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.10.2008, 18:35

Выскакивает ошибка доступа после прохождения setlength
Добрый вечер. Выскакивает ошибка доступа после прохождения setlength(mas,i+1)....

Не работает setLength с двухмерными массивами
почему не работает setLength с двухмерным массивам хотя в справки описано :...

SetLength работает с динамическим массивом переданым через параметры функции?
есть функция myfunk(var N:Array of integer):boolean; begin SetLength(N,10);...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru