Solved

Record and pointers

Posted on 2004-03-26
21
553 Views
Last Modified: 2010-04-05
I have a record with strings, integers and booleans.
I read the data into the record from several files and need to store them in the memory.

In my program I have an array [1..500] of record.
I don't know how many records are to be used for each time, so 500 here is just a guess. I could set it to 1000 or even 2000 just to be sure but I see it as a waste of memory.

I think the best here would be to use a pointer for the record. I have forgot most about using pointers so I need some help here.

I need to know how many reords are read and also access any of them by index.
I know you experts can help me

If you could give me a litle sample how to declare, allocate memory, read data into the record and access any of it.
0
Comment
Question by:mieow
21 Comments
 
LVL 11

Accepted Solution

by:
shaneholmes earned 150 total points
ID: 10689630
You could keep track of them using a global variable

Var

 gCount: Integer;

When you add one, inc(gCount)

when you delete one, dec(gCount)

Look at using dynamic arrays, so it will grow as you add the records. (SetLength)

If you need any more help, let me know


Shane
0
 
LVL 17

Expert Comment

by:mokule
ID: 10689638
What about just using

SetLength(YourArray,Count);
It allows You manage size at runtime
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10689852
"Look at using dynamic arrays, so it will grow as you add the records. (SetLength)"

<Smile>

Shane
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 10689898
i would prefer a tlist, more comfortable
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10689928
Me too, and I think in a earlier post i tried to get him to convert over to Classes versus records....

Shane
0
 

Author Comment

by:mieow
ID: 10690033
Shane, I have never used dynamic arrays before. I read about them in Delphi Help.
Just to be sure I got it right, can you write me a small code sample and I give you another 50 points. :)

What I do in my program is scanning for files and store some info about them in a record.

Like this:

Type

mydata = record
  data1 : string;
  data2 : string;
  count : integer;
  douse : boolean;
end;

var
storeddata : array of mydata // Is this the correct way to declare ?
cnt : integer;

begin

 repeat
  readfiles;
  inc(cnt)
    // read data into storeddata[cnt]  <--  Do I have to allocate memory for each read?
   
 until no more files;

end;






0
 

Author Comment

by:mieow
ID: 10690039
Oops, you reply while I'm typing :)

How could I use a tlist and why is it better?
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10690147

How about TOBjectList (change your record to an object)

then you can just add using  

StoreData.Add(Data)


unit Test;

interface

Uses Classes, Contnrs;

type
Tmydata = class
  data1 : string;
  data2 : string;
  count : integer;
  douse : boolean;
end;

var
 Data: TmyData;
 StoreData: TObjectList;
 
implementation

initialization
begin
 //create list
 StoreData:= TObjectList.Create;
 //set owns objects so they are all free when list is destroyed
 StroreData.OwnObjects:= True;
end;

finalization
begin
 //free list
 StoreData.Free;
end;
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10690158
I can also help you read and write these to file

Shane
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10690211
unit Test;

interface

Uses Classes, Contnrs;

type

Tmydata = class
  data1 : string;
  data2 : string;
  count : integer;
  douse : boolean;
end;

function ReadStreamStr(Stream : TStream) : string;
function ReadStreamInt(Stream : TStream) : integer;
procedure WriteStreamInt(Stream : TStream; Num : integer);
procedure WriteStreamStr(Stream : TStream; Str : string);

procedure SaveToFile(FileName: String);
procedure LoadFromFile(FileName: String);

var
 Data: TmyData;
 StoreData: TObjectList;
 
implementation


{procedure WriteStreamInt(Stream : TStream; Num : integer);
begin
 Stream.Write(Num, SizeOf(Integer));
end;

procedure WriteStreamStr(Stream : TStream; Str : string);
var
 StrLen : integer;
begin
 StrLen := Length(Str);
 WriteStreamInt(Stream, StrLen);
 Stream.Write(Str[1], StrLen);
end;}

function ReadStreamInt(Stream : TStream) : integer;
begin
 Stream.Read(Result, SizeOf(Integer));
end;


function ReadStreamStr(Stream : TStream) : string;
var
 StrLen : integer;
begin
 StrLen := ReadStreamInt(Stream);
 if StrLen > -1 then
 begin
  SetLength(Result, StrLen);
  Stream.Read(Result[1], StrLen);
 end
 else
 Result := '';
end;

procedure SaveToFile(FileName: String);
var
 MemStr: TMemoryStream;
 I, J: Integer;
begin
 MemStr:= TMemoryStream.Create;
 WriteStreamInt(MemStr,StoreData.Count);
 for I:= 0 to StoreData.Count - 1 do
 begin
  WriteStreamStr(MemStr, TMyData(StoreData[I]).Data1);
  WriteStreamStr(MemStr, TMyData(StoreData[I]).Data2);
  WriteStreamInt(MemStr, TMyData(StoreData[I]).Count);
  end;
 MemStr.SaveToFile(FileName);
 MemStr.Free;
end;

procedure LoadFromFile(FileName: String);
var
 MemStr: TMemoryStream;
 I, J, DCount: Integer;
 AData1, AData2: String;
 ACount: Integer;
 AData: TMyData;
begin
 MemStr:= TMemoryStream.Create;
 MemStr.LoadFromFile(FileName);
 DCount:= ReadStreamInt(MemStr);
 for I:= 0 to DCount - 1 do
  begin
   AData1:= ReadStreamStr(MemStr);
   AData2:= ReadStreamStr(MemStr);
   ACount:=  ReadStreamInt(MemStr);
   AData:= TMyData.Create;
   AData.Data1:= AData1;
   AData.Data2:= AData2;
   AData.Count:= ACount;
   StoreData.Add(AData)
  end;
 end;
 MemStr.Free;
end;

initialization
begin
 //create list
 StoreData:= TObjectList.Create;
 //set owns objects so they are all free when list is destroyed
 StroreData.OwnObjects:= True;
end;

finalization
begin
 //free list
 StoreData.Free;
end;
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 11

Expert Comment

by:shaneholmes
ID: 10690273
I can send you an example if you provide me your email address...

Shane
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10690341
OK, here it is all tested  (fixed the typos, and added the boolean field (DoUse) as well).

unit Unit2;

interface

Uses Classes, Contnrs;

type

Tmydata = class
  data1 : string;
  data2 : string;
  count : integer;
  douse : boolean;
end;

function ReadStreamStr(Stream : TStream) : string;
function ReadStreamInt(Stream : TStream) : integer;
procedure WriteStreamInt(Stream : TStream; Num : integer);
procedure WriteStreamStr(Stream : TStream; Str : string);

procedure SaveToFile(FileName: String);
procedure LoadFromFile(FileName: String);

var
 Data: TmyData;
 StoreData: TObjectList;
 
implementation


procedure WriteStreamInt(Stream : TStream; Num : integer);
begin
 Stream.Write(Num, SizeOf(Integer));
end;

procedure WriteStreamStr(Stream : TStream; Str : string);
var
 StrLen : integer;
begin
 StrLen := Length(Str);
 WriteStreamInt(Stream, StrLen);
 Stream.Write(Str[1], StrLen);
end;

function ReadStreamInt(Stream : TStream) : integer;
begin
 Stream.Read(Result, SizeOf(Integer));
end;


function ReadStreamStr(Stream : TStream) : string;
var
 StrLen : integer;
begin
 StrLen := ReadStreamInt(Stream);
 if StrLen > -1 then
 begin
  SetLength(Result, StrLen);
  Stream.Read(Result[1], StrLen);
 end
 else
 Result := '';
end;

procedure SaveToFile(FileName: String);
var
 MemStr: TMemoryStream;
 I, J: Integer;
begin
 MemStr:= TMemoryStream.Create;
 WriteStreamInt(MemStr,StoreData.Count);
 for I:= 0 to StoreData.Count - 1 do
 begin
  WriteStreamStr(MemStr, TMyData(StoreData[I]).Data1);
  WriteStreamStr(MemStr, TMyData(StoreData[I]).Data2);
  WriteStreamInt(MemStr, TMyData(StoreData[I]).Count);
  if TMyData(StoreData[I]).DoUse then
   WriteStreamStr(MemStr, 'True')
  else
   WriteStreamStr(MemStr, 'False');
  end;
 MemStr.SaveToFile(FileName);
 MemStr.Free;
end;

procedure LoadFromFile(FileName: String);
var
 MemStr: TMemoryStream;
 I, J, DCount: Integer;
 ADoUse, AData1, AData2: String;
 ACount: Integer;
 AData: TMyData;
begin
 MemStr:= TMemoryStream.Create;
 MemStr.LoadFromFile(FileName);
 DCount:= ReadStreamInt(MemStr);
 for I:= 0 to DCount - 1 do
  begin
   AData1:= ReadStreamStr(MemStr);
   AData2:= ReadStreamStr(MemStr);
   ACount:=  ReadStreamInt(MemStr);
   AData:= TMyData.Create;
   AData.Data1:= AData1;
   AData.Data2:= AData2;
   AData.Count:= ACount;
   ADoUse:= ReadStreamStr(MemStr);
   if ADoUse = 'True' then AData.douse:= True
    else
   AData.douse:= False;
   StoreData.Add(AData);
  end;
 MemStr.Free;
end;

initialization
begin
 //create list
 StoreData:= TObjectList.Create;
 //set owns objects so they are all free when list is destroyed
 StoreData.OwnsObjects:= True;
end;

finalization
begin
 //free list
 StoreData.Free;
end;
end.
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10690400
Now,

when you want to add to the list you just

var
 Adata: TMyData;


 AData:= TMyData.Create;
 AData.Data1:= 'Hello';
 AData.Data2:= 'GoodBye';
 AData.DoUse:= True;

 StoreData.Add(AData);


 Look at TObjectList in the Delphi help for all of the available methods, such as

 delete, indexOf, etc.

I use this method alot in junction with a TListview, to display its data. Then the index of a TListview can correspond with the index of the item in the ObjectList.


Shane
0
 

Author Comment

by:mieow
ID: 10690403
Shane, I very much appreciate your efforts to help me.

Using Objectlists might be the best solution, but I think that is above my level and I will get in trouble when ever I have to do some changes in code in the future. :)
( Note to myself: get some good Delphi books)
I will still copy and paste your code and do some experiment and try to figure out how it works.

At this moment I think the best for me would be to use dynamic arrays. Can you go back to my previous post and give me a sample code how to use them.
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10690413
Yes, hold one sec
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10690440
While i build you a little example, try reading this article:

Down alittle ways, it explains how Dynamic Arrays work

http://delphi.about.com/library/weekly/aa041800a.htm

Shane
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10690491


var
 MyDataArray = Array of MyData;

 set its length as it grows, by calling setLength
 SetLength(MyDataArray,1);

 // add record to array
 MyDataArray[0]= MyData;


Shane
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10690572

//Deinitialise the Dynamic Array
 SetLength(MyDataArray, 0);

Shane
   
0
 

Author Comment

by:mieow
ID: 10690854
Shane, that works perfect .

Thank you for taking your time to help me.

I will use dynamic arrays in the project I'm working with now, but I will study your code example with Objectlists and try to figure out how it works.

0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10690862
Your welcome

Good Luck!

Shane
0
 
LVL 14

Expert Comment

by:DragonSlayer
ID: 10690864
... i still think a TList/ObjectList approach is "cleaner" :-)
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now