Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.09.2011, 00:03   #1
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию незаполненные массивы и память

Здрастуйте =)
у меня вот какой вопрос:

допустим есть array of TStrings.
что будет если я SetLength(array,1000),
а потом array[999]:=TStringList.Create; ?

т.е. по-идее я создам один единственный TStringList,
но как это скажется на памяти, с учетом того что он 999-й в массиве?
весь остальной массив пустой.

p.s.
пытаюсь придумать систему хранения табличных данных.
кроме как array of TStrings ничего не придумал.
может есть у кого гениальные идеи на этот счет?
Как бы это сделал "правильный" програмер?

Последний раз редактировалось xrob; 03.09.2011 в 00:05.
xrob вне форума Ответить с цитированием
Старый 03.09.2011, 00:10   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

да собственно после SetLength вы уже выделили память на 1000 указателей(помним что объекты по ссылкам хранятся)
или ччего вы ожидаете?
лишь один элемент массива будет указывать на объект, остальные мусор.
Цитата:
может есть у кого гениальные идеи на этот счет?
Как бы это сделал "правильный" програмер?
зависит от активности изменения количества этих списков.
тут или массив списков или список списков.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.

Последний раз редактировалось Пепел Феникса; 03.09.2011 в 00:12.
Пепел Феникса вне форума Ответить с цитированием
Старый 03.09.2011, 00:11   #3
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

SetLength(array,1000) и отведет память для 1000 указателей на TStrings. array[999]:=TStringList.Create запишет указатель в ранее отведенное место.
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 03.09.2011, 00:12   #4
ViktorXP
Форумчанин
 
Аватар для ViktorXP
 
Регистрация: 24.11.2006
Сообщений: 108
По умолчанию

Цитата:
Сообщение от xrob Посмотреть сообщение
допустим есть array of TStrings.
что будет если я SetLength(array,1000),
а потом array[999]:=TStringList.Create; ?
Интересно другое. что произойдет если ты следующей же строкой сделаешь
SetLength(array, 0);

Цитата:
Сообщение от xrob Посмотреть сообщение
т.е. по-идее я создам один единственный TStringList,
но как это скажется на памяти, с учетом того что он 999-й в массиве?
весь остальной массив пустой.
умнож 1000 на 4 (или на 8 если ты собираешь под x64)

Цитата:
Сообщение от xrob Посмотреть сообщение
p.s.
пытаюсь придумать систему хранения табличных данных.
кроме как array of TStrings ничего не придумал.
может есть у кого гениальные идеи на этот счет?
Как бы это сделал "правильный" програмер?
База данных? не?
ViktorXP вне форума Ответить с цитированием
Старый 03.09.2011, 00:27   #5
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию

да, вот как раз я и подумал потом про указатели.
и если следовать логике указателей, то

array[x]:=TStringList.Create;

равно

s:=TStringList.Create;
array[x]:=s;

да?

а что вы можете сказать вот об этом?

type
TXStrings = array of string;
var
Test:array of TXStrings;

т.е. массив массивов из строк... такое вообще допустимо?
компилится нормально.
только я вообще не понял как с этим работать...

Test[x][y] - ведь не так же???


а после SetLength(array, 0); насколько я могу понимать, выделится память под 0 элементов массива.
при этом то что было им раньше занято останется, пока не будет перезаписано чем-то другим.
а если еще после этого снова сделать SetLength(array, 999); то все вернется на свои места,
или перезапишется в null, я прав?

ViktorXP, ну мою задачу я озвучил - реализовать систему хранения табличной информации.
т.е. типа того:

"что-то" "нечто" "ничего" "еще что-нибудь"
"что-то" "нечто" "ничего" "еще что-нибудь"
и т.д.

база данных это или нет - вопрос субъективный.
для кого-то это база, для кого-то это смех веселый =)
вот как-то так.
xrob вне форума Ответить с цитированием
Старый 03.09.2011, 00:33   #6
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Цитата:
Сообщение от xrob Посмотреть сообщение
Здрастуйте =)
у меня вот какой вопрос:

допустим есть array of TStrings.
что будет если я SetLength(array,1000),
а потом array[999]:=TStringList.Create; ?

т.е. по-идее я создам один единственный TStringList,
но как это скажется на памяти, с учетом того что он 999-й в массиве?
весь остальной массив пустой.

p.s.
пытаюсь придумать систему хранения табличных данных.
кроме как array of TStrings ничего не придумал.
может есть у кого гениальные идеи на этот счет?
Как бы это сделал "правильный" програмер?
я бы написал свой класс на основе TobjectList и TObject
Вот скелет:
Код:
unit Unit2;

interface

uses SysUtils,Windows,Contnrs,Classes;

type
  TMyDB = class(TObject)
  private
  fStrings:TStringList;
  public
  property myStrings:TStringList read fStrings write fStrings;
  constructor Create;
  destructor Destroy; override;
  end;

type
  TMyDBList=class(TObjectLIst)
  private
  function GetDB(aIndex:Integer):TMyDB;
  public
    property DB[aIndex:Integer]:TMyDB read GetDB;
    procedure AddDB(aDB:TMyDB);
    procedure DeleteDB(aIndex:Integer);
    constructor Create; overload;
    constructor Create(aDBCount:Integer); overload;
    destructor Destroy; override;
  end;

implementation

{ TMyDB }

constructor TMyDB.Create;
begin
  inherited;
  fStrings:=TStringList.Create;
end;

destructor TMyDB.Destroy;
begin
  FreeAndNil(fStrings);
  inherited;
end;

{ TMyDBList }

procedure TMyDBList.AddDB(aDB: TMyDB);
begin
  Add(aDB);
end;

constructor TMyDBList.Create;
begin
  inherited;
  <

  >
end;

constructor TMyDBList.Create(aDBCount: Integer);
var
  vDB:TMyDB;
  i:Integer;
begin
  for i:=0 to aDBCount -1 do
  begin
    vDB:=TMyDB.Create;
    addDB(vDB);
  end;
end;

procedure TMyDBList.DeleteDB(aIndex: Integer);
begin
  DB[aIndex].Free;
end;

destructor TMyDBList.Destroy;
begin

  inherited;
end;

function TMyDBList.GetDB(aIndex: Integer): TMyDB;
begin
  Result:=(Items[aIndex] as TMyDB);
end;

end.
Комментировать нужно?
Человек_Борща вне форума Ответить с цитированием
Старый 03.09.2011, 00:36   #7
ViktorXP
Форумчанин
 
Аватар для ViktorXP
 
Регистрация: 24.11.2006
Сообщений: 108
По умолчанию

Цитата:
Сообщение от xrob Посмотреть сообщение
array[x]:=TStringList.Create;

равно

s:=TStringList.Create;
array[x]:=s;

да?
Да.

Цитата:
Сообщение от xrob Посмотреть сообщение
а что вы можете сказать вот об этом?

type
TXStrings = array of string;
var
Test:array of TXStrings;

т.е. массив массивов из строк... такое вообще допустимо?
компилится нормально.
только я вообще не понял как с этим работать...

Test[x][y] - ведь не так же???
А почему бы и нет? ну можешь и так указать
Test[x,y]компилятор поймет.


Цитата:
Сообщение от xrob Посмотреть сообщение
перезапишется в null, я прав?
Да (хотя скорее в nil )
Цитата:
Сообщение от xrob Посмотреть сообщение
ViktorXP, ну мою задачу я озвучил - реализовать систему хранения табличной информации.
т.е. типа того:

"что-то" "нечто" "ничего" "еще что-нибудь"
"что-то" "нечто" "ничего" "еще что-нибудь"
и т.д.

база данных это или нет - вопрос субъективный.
для кого-то это база, для кого-то это смех веселый =)
вот как-то так.
если у тебя 2009+ тогда посмотри на TDictionary из модуля Generics.Collections
если у тебя ниже тогда посмотри в сторону TBucketList из модуля Contnrs
(TBucketList не так удобно как сие можно реализовать на TDictionary)

Последний раз редактировалось ViktorXP; 03.09.2011 в 00:40.
ViktorXP вне форума Ответить с цитированием
Старый 03.09.2011, 00:47   #8
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию

Add(aDB); это видимо функция описанная в классе, от которого вы унаследовали TMyDBList, да?
а TMyDB содержит TStringList. а функция Add(aDB); кладет куда-то в TMyDBList экземпляр TMyDB, так?
по сути это то же самое что и array of TStrings, только основано на более высокоуровневых объектах.
или я не прав? мне кажется вы слишком сложно завернули для моей задачи. и слова страшные используете: MyDB, ListDB... "список баз данных"... у меня вызывает оочень "тяжелые" ассоциации =)
а я хочу сделать легкий доступ к своим данным типа как Cells[x,y] в StringGrid.
но за идею спасибо =)

ViktorXP, у меня Delphi 10 lite ))))
там даже TWebBrowser нету - достал из Delphi 7, на форму ручками прописываю, через Create ))
----------------------

а array of string; тоже указатели?
я надеюсь SetLength(array,1000); не займет 255*1000 памяти?

Последний раз редактировалось xrob; 03.09.2011 в 01:06.
xrob вне форума Ответить с цитированием
Старый 03.09.2011, 01:10   #9
notHaker
Форумчанин
 
Аватар для notHaker
 
Регистрация: 01.12.2009
Сообщений: 569
По умолчанию

Цитата:
Add(aDB); это видимо функция описанная в классе, от которого вы унаследовали TMyDBList, да?
а TMyDB содержит TStringList. а функция Add(aDB); кладет куда-то в TMyDBList экземпляр TMyDB, так?
по сути это то же самое что и array of TStrings, только основано на более высокоуровневых объектах.
или я не прав? мне кажется вы слишком сложно завернули для моей задачи. и слова страшные используете: MyDB, ListDB... "список баз данных"... у меня вызывает оочень "тяжелые" ассоциации =)
а я хочу сделать легкий доступ к своим данным типа как Cells[x,y] в StringGrid.
но за идею спасибо =)

ViktorXP, у меня Delphi 10 lite ))))
там даже TWebBrowser нету - достал из Delphi 7, на форму ручками прописываю, через Create ))
Никто вам ничего не заворачивал. Просто с объектами TList удобней. Там и добавить и удалить можно без фрагментирования и утечек (если запилить уничтожение объекта при наследовании).
Да и доступ примерно тот же.
Код:
List.Items[x].Items[y]
Код - это работа, а работа стоит денег.

pz-game.ru. 2d зомби-сурвивал для олдфагов.
notHaker вне форума Ответить с цитированием
Старый 03.09.2011, 01:13   #10
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

с массивами можно таких дел наворотить...

Комментирую:
Код:
unit Unit2;

interface

uses SysUtils,Windows,Contnrs,Classes;

type
  TMyDB = class(TObject)
  private
  fStrings:TStringList;
  public
//Свойство обеспечивающее доступ к внутренней переменой fStrings
  property myStrings:TStringList read fStrings write fStrings;
  constructor Create;
  destructor Destroy; override;
  end;

type
  TMyDBList=class(TObjectLIst) 
  private
  function GetDB(aIndex:Integer):TMyDB;
  public
    property DB[aIndex:Integer]:TMyDB read GetDB; 
    procedure AddDB(aDB:TMyDB);
    procedure DeleteDB(aIndex:Integer);
    constructor Create; overload;
    constructor Create(aDBCount:Integer); overload;
    destructor Destroy; override;
  end;

implementation

{ TMyDB }

constructor TMyDB.Create;
begin
  inherited;
  fStrings:=TStringList.Create;
//Создадим список строк
end;

destructor TMyDB.Destroy;
begin
//Уничтожим список строк
  FreeAndNil(fStrings);
  inherited;
end;

{ TMyDBList }

procedure TMyDBList.AddDB(aDB: TMyDB);
begin
  Add(aDB);
//Добавим обьект myDB в список
end;

constructor TMyDBList.Create;
begin
  inherited;

//Тут код при создании списка БД
end;

//Конструкктор с возможностью создать список БД с указанным кол-вом БД
constructor TMyDBList.Create(aDBCount: Integer);
var
  vDB:TMyDB;
  i:Integer;
begin
  for i:=0 to aDBCount -1 do
  begin
    vDB:=TMyDB.Create;
    addDB(vDB);
  end;
end;

procedure TMyDBList.DeleteDB(aIndex: Integer);
begin
//Уничтожиим обьект 
DB[aIndex].Destroy; 
//удалим его из списка(зачем занимать место?)
Delete(aIndex);
end;

destructor TMyDBList.Destroy;
begin
  {
 Сам уничтожает обькты
 }
  inherited;
end;

{
Возвращает нам элемент списка DBLIst по индексу
}
function TMyDBList.GetDB(aIndex: Integer): TMyDB;
begin
  Result:=(Items[aIndex] as TMyDB);
end;

end.
А вообще если хотите многомерный класс, то вместо tMyDB используйте самого себя.... tMyDBList и тогда получите иерархическую структуру...

А ообще это даже выше и проще массивов.. С масивами всегда много проблем(Особенно с многомерными).

Массив может быть каким угодно:
Код:
Type
  myArray = array of integer; //одномерный
{

     |_ 

}

Type
  myArray2 = array of array of Integer; //Двухмерный
{

    |_
      |_ 

 }

Type
  myArray3 = array of array of array of Integer; //Трёхмерный

{

    |_
      |_
        |_ 
}
и скаждым витком, сложно уследить за обькстами внутри, особенно если эти обьеты нужно уничтожать...

Почитайте блог gunsmoker'а там много чего есть и про переменные и про массивы, в общем куча полезной информации=)

Последний раз редактировалось Человек_Борща; 03.09.2011 в 01:18.
Человек_Борща вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Виртуальная память ordoss Общие вопросы C/C++ 1 12.01.2011 18:00
Динамическая память. spotmc13 Паскаль, Turbo Pascal, PascalABC.NET 5 20.09.2010 17:08
память процесса T_I_T_A_N Общие вопросы Delphi 7 28.06.2010 13:52
Память Ghennadiy Общие вопросы Delphi 9 25.08.2009 09:23
динамическая память aka_faith Общие вопросы C/C++ 47 12.06.2009 12:35