Цитата:
Сообщение от Евгений79
Так все работает отлично. Память сильно не расходуется.
но если заменить строку list.Add(str);
на list.Add(str + '1');
или
str2:=str + '1';
list.Add(str2);
то приложение вылетает с руганью на окончание памяти.
|
Это всё потому что String (точнее AnsiString) является типом с управляемым временем жизни со счётчиком ссылок.
Пример:
Код:
str := StringOfChar('X', 1024 * 1024); // Создаём новую строку str размером в мегабайт
str2 := str + '1'; // Создаём новую строку str2 и копируем в неё содержимое str плюс сивол '1'
for i := 1 to 1000000 do
begin
list.Add(str2); // В список list добавляется миллион раз ссылка на строку str2
end;
В этом примере только один раз выделяется память под строку str2 и в цикле в список list миллион раз добавляется ссылка на эту строку. Ссылка это просто указатель (Pointer), который в Win32 занимает всего 4 байта, что в сумме займёт 4*1000000=4000000 байт под эти указатели, плюс мегабайт для самой строки.
Другой пример:
Код:
str := StringOfChar('X', 1024 * 1024); // Создаём новую строку str размером в мегабайт
for i := 1 to 1000000 do
begin
str2 := str + '1'; // Создаём новую строку str2 и копируем в неё содержимое str плюс сивол '1'
list.Add(str2); // В список list добавляется миллион раз ссылка на строку str2
end;
В этом примере всё совсем по-другому. Здесь миллион раз выделяется память под новую строку и ссылка на неё добавляется в список list. Сколько займёт памяти миллион мегабайтных строк подсчитать не составит труда.
