Mega Code Archive

 
Categories / Delphi / Examples
 

How to fix data segment too large errors

Many of us had to find out that Windows (not a Delphi problem !) has serious limitations about how many controls you can use on forms. Especially large forms with over 100, 120 controls (i.e.: Edit-Controls, Buttons, but also Panels and Images) can produce loading problems ("error creating form xx"). Another problem is the limited size of the Data Segment, which is only 64 KB in size and cannot be enlarged anyhow. Since the Delphi RTL already uses a few KB's of this space, many of us already had contact to "Compiler error 49 ("Data Segment too large")... How can you minimize the use of the Data Segment ? The Data Segment commonly consists of the following: Global Variables Stack space (1 MB automatically -virtually- allocated) Local Heap PChar Literals Typed Constants Virtual Method Tables of objects & classes You can : Try to make your strings smaller Use Mystring: String[size] instead of unqualified strings. Example: VAR StrX: String; { takes 255 bytes } VAR StrX: String[5]; { takes up on ly 5 or 6 } Try to reduce your Stack space in the Linker options Usually you can reduce it to a much smaller value without troubles. Split the data into different units. Put your things (see list above) in group blocks ! The Delphi compiler is smart enough not to link in any data that isn't used, but this is only possible if everything in the block where this data was declared isn't used. So, put your things that belong together in their own VAR.., TYPE.. and CONST.. blocks to avoid linking them in if you might use only one part of it. Allocate static data (see list above) on the heap and make it dynamic ! Means: use pointers and GetMem/New ! This will again decrease execution speed and requires another layer of indirection (a pointer dereference). Example: instead of coding TYPE a1: ARRAY[1..] OF a2: .. you should code: TYPE TArrRec = RECORD a1: ARRAY[1..] OF a2: .. END; VAR ArrRec: ^TArrRec; BEGIN TRY NEW(ArrRec); { use your Data like ArrRec^.a1[3]; here } FINALLY DISPOSE(ArrRec); END; END; Calculate values each time you need them and don't use lookup tables instead. Well, this uses more code space and execution time, but fixes your bottleneck.. Windows programs can eliminate the Data Size used up by PChar literals by using String Tables. This also enables the translation (internationalisation) of the application itself - Delphi already uses String Tables heavily ! Move all your strings to a resource .RES file and load them dynamically. "What I usually do is to define one "global" object. It's usually a class - created when the program starts and destroyed as it goes away. All of the things that the various units of the program need to talk among themselves and to each other are stored in Global. When the things that are global need to be larger than 32k or so (even in Win95..transportability is still important to me..), it becomes a method. Voila, now the class hides all of the details of physically locating and storing/retrieving the global information - exactly, of course, as a class ought to do. It works. Even in Win95-land, it works." (by Sundial Services) More questions ? Maybe Klaus Hartnegg's 64 KB-FAQ can help you ! Find related information on Borland's Pages: [1], [2] !