Hello,
I have a basic question concerning strings and array memory representation in GPC. To my amusement I noticed that in the following program the string assigned to an array element cannot be then restored from the array itself. So probably an array of strings is not represented in memory just like an array of simple type, and cannot (?) be simply getmem-ed ?
program test; type NameStr=String[8]; shortarray=array[1..3] of NameStr;
var n:NameStr; a:^shortarray; i:integer;
begin getmem(a,3*sizeof(NameStr)); n:='12345678'; for i:=1 to 3 do begin a^[i]:=n; writeln('n = ',n) writeln('a^[i] = ',a^[i]); end; end.
As a result the value of a^[i] is an empty string after the assignment; I will be very grateful for any answers or comments (I use gpc version 20010502, based on 2.95.3 20010315). Regards, Adam Naumowicz
-------------------------------------- WWW: http://math.uwb.edu.pl/~adamn/ --------------------------------------
Adam Naumowicz wrote:
Hello,
I have a basic question concerning strings and array memory representation in GPC. To my amusement I noticed that in the following program the string assigned to an array element cannot be then restored from the array itself. So probably an array of strings is not represented in memory just like an array of simple type, and cannot (?) be simply getmem-ed ?
program test; type NameStr=String[8]; shortarray=array[1..3] of NameStr;
var n:NameStr; a:^shortarray; i:integer;
begin getmem(a,3*sizeof(NameStr)); n:='12345678'; for i:=1 to 3 do begin a^[i]:=n; writeln('n = ',n) writeln('a^[i] = ',a^[i]); end; end.
As a result the value of a^[i] is an empty string after the assignment; I will be very grateful for any answers or comments (I use gpc version 20010502, based on 2.95.3 20010315).
Strange. For me it works as expected (djgpp 20010623 based on 2.95.3) Maurice
On 10 Jul 2001, at 18:24, Adam Naumowicz wrote:
Hello,
I have a basic question concerning strings and array memory representation in GPC. To my amusement I noticed that in the following program the string assigned to an array element cannot be then restored from the array itself. So probably an array of strings is not represented in memory just like an array of simple type, and cannot (?) be simply getmem-ed ?
program test; type NameStr=String[8]; shortarray=array[1..3] of NameStr;
var n:NameStr; a:^shortarray; i:integer;
begin getmem(a,3*sizeof(NameStr));
This is your problem. Use 'New' instead of 'getmem' - i.e., New (a, 3 * sizeof (NameStr)); or New (a, sizeof (shortarray)); or better still, just "New (a);"
Best regards, The Chief --------- Prof. Abimbola Olowofoyeku (The African Chief) Author of Chief's Installer Pro for Win32 Email: African_Chief@bigfoot.com http://www.bigfoot.com/~african_chief/
On Wed, 11 Jul 2001, Prof. A Olowofoyeku (The African Chief) wrote:
On 10 Jul 2001, at 18:24, Adam Naumowicz wrote:
Hello,
I have a basic question concerning strings and array memory representation in GPC. To my amusement I noticed that in the following program the string assigned to an array element cannot be then restored from the array itself. So probably an array of strings is not represented in memory just like an array of simple type, and cannot (?) be simply getmem-ed ?
program test; type NameStr=String[8]; shortarray=array[1..3] of NameStr;
var n:NameStr; a:^shortarray; i:integer;
begin getmem(a,3*sizeof(NameStr));
This is your problem. Use 'New' instead of 'getmem' - i.e., New (a, 3 * sizeof (NameStr)); or New (a, sizeof (shortarray)); or better still, just "New (a);"
Thanks for your answers. But I want my sources to stay BP/Delphi compatible... I still don't know what is wrong with the getmem call. Maybe I should try this example with a newer compiler as Maurice says it works fine for him. It worked fine for me with BP, Delphi and FPC, but all those handle strings in somewhat different manner than GPC. Why is new better than getmem in this example ? Regards, Adam Naumowicz
-------------------------------------- WWW: http://math.uwb.edu.pl/~adamn/ --------------------------------------
On 11 Jul 2001, at 11:21, Adam Naumowicz wrote:
[...]
begin getmem(a,3*sizeof(NameStr));
This is your problem. Use 'New' instead of 'getmem' - i.e., New (a, 3 * sizeof (NameStr)); or New (a, sizeof (shortarray)); or better still, just "New (a);"
Thanks for your answers. But I want my sources to stay BP/Delphi compatible...
Both BP and Delphi understand "New (a);".
I still don't know what is wrong with the getmem call. Maybe I should try this example with a newer compiler as Maurice says it works fine for him.
I have the latest snapshot of the compiler, and getmem does not work in this example.
It worked fine for me with BP, Delphi and FPC, but all those handle strings in somewhat different manner than GPC. Why is new better than getmem in this example ?
It is because of the format of GPC strings. Read: http://agnes.dida.physik.uni-essen.de/~gnu-pascal/gpc_37.html#SEC37
Best regards, The Chief --------- Prof. Abimbola Olowofoyeku (The African Chief) Author of Chief's Installer Pro for Win32 Email: African_Chief@bigfoot.com http://www.bigfoot.com/~african_chief/
On Wed, 11 Jul 2001, Prof. A Olowofoyeku (The African Chief) wrote:
On 11 Jul 2001, at 11:21, Adam Naumowicz wrote:
[...]
begin getmem(a,3*sizeof(NameStr));
This is your problem. Use 'New' instead of 'getmem' - i.e., New (a, 3 * sizeof (NameStr)); or New (a, sizeof (shortarray)); or better still, just "New (a);"
Thanks for your answers. But I want my sources to stay BP/Delphi compatible...
Both BP and Delphi understand "New (a);".
I believe that NEW with size parameter is not accepted.
I still don't know what is wrong with the getmem call. Maybe I should try this example with a newer compiler as Maurice says it works fine for him.
I have the latest snapshot of the compiler, and getmem does not work in this example.
It worked fine for me with BP, Delphi and FPC, but all those handle strings in somewhat different manner than GPC. Why is new better than getmem in this example ?
It is because of the format of GPC strings. Read: http://agnes.dida.physik.uni-essen.de/~gnu-pascal/gpc_37.html#SEC37
Yes I read this. But the NameStr (String[8]) I use is of a fixed size and I want to getmem the array, not the strings ... Then I assign a value of a variable of that type to an element of the array that should (?) be a compact sequence of its elements. Regards, Adam Naumowicz
-------------------------------------- WWW: http://math.uwb.edu.pl/~adamn/ --------------------------------------
This is your problem. Use 'New' instead of 'getmem' - i.e., New (a, 3 * sizeof (NameStr)); or New (a, sizeof (shortarray)); or better still, just "New (a);"
Thanks for your answers. But I want my sources to stay BP/Delphi compatible... I still don't know what is wrong with the getmem call. Maybe I should try this example with a newer compiler as Maurice says it works fine for him. It worked fine for me with BP, Delphi and FPC, but all those handle strings in somewhat different manner than GPC. Why is new better than getmem in this example ?
Because automatic initialisation is run that way.
This also goes for FPC and Delphi, not only GPC. Probably you were just lucky, or the compiler was able to detect what you meant.
Or Delphi and FPC used shortstring for this, and GPC schemata. But if you'd use automated types in FPC/Delphi (like ansistring/dynamic arrays) you could run into these problems too. NEW is really better.
On Wed, 11 Jul 2001, Marco van de Voort wrote:
This is your problem. Use 'New' instead of 'getmem' - i.e., New (a, 3 * sizeof (NameStr)); or New (a, sizeof (shortarray)); or better still, just "New (a);"
Thanks for your answers. But I want my sources to stay BP/Delphi compatible... I still don't know what is wrong with the getmem call. Maybe I should try this example with a newer compiler as Maurice says it works fine for him. It worked fine for me with BP, Delphi and FPC, but all those handle strings in somewhat different manner than GPC. Why is new better than getmem in this example ?
Because automatic initialisation is run that way.
This also goes for FPC and Delphi, not only GPC. Probably you were just lucky, or the compiler was able to detect what you meant.
Or Delphi and FPC used shortstring for this, and GPC schemata. But if you'd use automated types in FPC/Delphi (like ansistring/dynamic arrays) you could run into these problems too. NEW is really better.
Thanks. I read the http://agnes.dida.physik.uni-essen.de/~gnu-pascal/gpc_37.html#SEC37 as the Chief suggested me to do, and now I can see what is the reason of such behaviour. But still I would like to allocate only a part of the array (to simulate a dynamic array - the piece of code I'm working with is from an old non-OOP Pascal version). I also cannot pass size to standard NEW call (at least in BP) ... Regards, Adam Naumowicz
-------------------------------------- WWW: http://math.uwb.edu.pl/~adamn/ --------------------------------------
Adam Naumowicz wrote:
On Wed, 11 Jul 2001, Marco van de Voort wrote:
This is your problem. Use 'New' instead of 'getmem' - i.e., New (a, 3 * sizeof (NameStr)); or New (a, sizeof (shortarray)); or better still, just "New (a);"
Thanks for your answers. But I want my sources to stay BP/Delphi compatible... I still don't know what is wrong with the getmem call. Maybe I should try this example with a newer compiler as Maurice says it works fine for him. It worked fine for me with BP, Delphi and FPC, but all those handle strings in somewhat different manner than GPC. Why is new better than getmem in this example ?
Because automatic initialisation is run that way.
This also goes for FPC and Delphi, not only GPC. Probably you were just lucky, or the compiler was able to detect what you meant.
Or Delphi and FPC used shortstring for this, and GPC schemata. But if you'd use automated types in FPC/Delphi (like ansistring/dynamic arrays) you could run into these problems too. NEW is really better.
Thanks. I read the http://agnes.dida.physik.uni-essen.de/~gnu-pascal/gpc_37.html#SEC37 as the Chief suggested me to do, and now I can see what is the reason of such behaviour. But still I would like to allocate only a part of the array (to simulate a dynamic array - the piece of code I'm working with is from an old non-OOP Pascal version). I also cannot pass size to standard NEW call (at least in BP) ...
Then declare shortarry as an array of string pointers instead of an array of strings, and allocate with new the number of strings you really need. I have done this many times in the past (for large matrices). Still now I prefer the dynamic arrays possible with the schemata of gpc and send BP to hell ... Maurice
Adam Naumowicz wrote:
Thanks. I read the http://agnes.dida.physik.uni-essen.de/~gnu-pascal/gpc_37.html#SEC37 as the Chief suggested me to do, and now I can see what is the reason of such behaviour. But still I would like to allocate only a part of the array (to simulate a dynamic array - the piece of code I'm working with is from an old non-OOP Pascal version). I also cannot pass size to standard NEW call (at least in BP) ...
You can use a GPC extension of {$define}. Put at the beginning of your source file these lines; {$ifdef __GPC__} {$define Getmem(x,y) New(x,y)} {$endif}
Then you can use 'Getmem' as usual, and GPC will substitute 'New' for it. Note that this is not visible outside the source file in which it was declared, so if you want to do the same in another file, you have to add those lines to that other file as well.
Best regards, The Chief --------- Prof. Abimbola Olowofoyeku (The African Chief) Author of Chief's Installer Pro for Win32 Email: African_Chief@bigfoot.com http://www.bigfoot.com/~african_chief/
On Wed, 11 Jul 2001, Prof. A Olowofoyeku (The African Chief) wrote:
Adam Naumowicz wrote:
Thanks. I read the http://agnes.dida.physik.uni-essen.de/~gnu-pascal/gpc_37.html#SEC37 as the Chief suggested me to do, and now I can see what is the reason of such behaviour. But still I would like to allocate only a part of the array (to simulate a dynamic array - the piece of code I'm working with is from an old non-OOP Pascal version). I also cannot pass size to standard NEW call (at least in BP) ...
You can use a GPC extension of {$define}. Put at the beginning of your source file these lines; {$ifdef __GPC__} {$define Getmem(x,y) New(x,y)} {$endif}
Then you can use 'Getmem' as usual, and GPC will substitute 'New' for it. Note that this is not visible outside the source file in which it was declared, so if you want to do the same in another file, you have to add those lines to that other file as well.
Thanks. I see that I just can't avoid some bigger modifications to the old code and it seems that adjusting it to new Pascal compilers' abilities is much better that using macros and other suggested tricky workarounds. Thanks again for all your replies. Regards, Adam Naumowicz
-------------------------------------- WWW: http://math.uwb.edu.pl/~adamn/ --------------------------------------
Prof. A Olowofoyeku (The African Chief) wrote:
Adam Naumowicz wrote:
Thanks. I read the http://agnes.dida.physik.uni-essen.de/~gnu-pascal/gpc_37.html#SEC37 as the Chief suggested me to do, and now I can see what is the reason of such behaviour. But still I would like to allocate only a part of the array (to simulate a dynamic array - the piece of code I'm working with is from an old non-OOP Pascal version). I also cannot pass size to standard NEW call (at least in BP) ...
You can use a GPC extension of {$define}. Put at the beginning of your source file these lines; {$ifdef __GPC__} {$define Getmem(x,y) New(x,y)} {$endif}
Then you can use 'Getmem' as usual, and GPC will substitute 'New' for it. Note that this is not visible outside the source file in which it was declared, so if you want to do the same in another file, you have to add those lines to that other file as well.
But that's not the same. The second parameter to New for schemata designates the number of elements whereas the second parameter to GetMem specifies the number of bytes. You might not immediately notice if you allocate as many elements as you meant to allocate bytes -- except by wasting some memory. ;-)
Frank
On 11 Jul 2001, at 13:34, Frank Heckenbach wrote:
[...]
You can use a GPC extension of {$define}. Put at the beginning of your source file these lines; {$ifdef __GPC__} {$define Getmem(x,y) New(x,y)} {$endif}
Then you can use 'Getmem' as usual, and GPC will substitute 'New' for it. Note that this is not visible outside the source file in which it was declared, so if you want to do the same in another file, you have to add those lines to that other file as well.
But that's not the same. The second parameter to New for schemata designates the number of elements whereas the second parameter to GetMem specifies the number of bytes. You might not immediately notice if you allocate as many elements as you meant to allocate bytes -- except by wasting some memory. ;-)
Yes, I see that now. It seems that he may just have to use {$ifdef} to switch between New and Getmem, or to use Getmem and then, with GPC, to set the capacity of the strings before assigning any value to them. But setting the capacity manually (e.g., "a^[i].capacity := 8") is not advisable - right? In which case we are back to the first alternative.
Best regards, The Chief --------- Prof. Abimbola Olowofoyeku (The African Chief) Author of Chief's Installer Pro for Win32 Email: African_Chief@bigfoot.com http://www.bigfoot.com/~african_chief/
Maurice Lombardi wrote:
Adam Naumowicz wrote:
Thanks. I read the http://agnes.dida.physik.uni-essen.de/~gnu-pascal/gpc_37.html#SEC37 as the Chief suggested me to do, and now I can see what is the reason of such behaviour. But still I would like to allocate only a part of the array (to simulate a dynamic array - the piece of code I'm working with is from an old non-OOP Pascal version). I also cannot pass size to standard NEW call (at least in BP) ...
Then declare shortarry as an array of string pointers instead of an array of strings, and allocate with new the number of strings you really need.
AFAICS, this is the only way that will work with the same code for GPC and BP.
If you really want to avoid it, you could use a little conditional compilation (though I usually discourage that ;-), like this:
program test;
type NameStr=String[8];
{$ifdef __GPC__}
type ShortArray (Size: Integer) = array [1 .. Size] of NameStr; PShortArray = ^ShortArray;
function AllocShortArray (Size: Integer) = p: PShortArray; begin New (p, Size) end;
{$else}
type ShortArray = array [1 .. MaxInt div SizeOf (NameStr)] of NameStr; PShortArray = ^ShortArray;
function AllocShortArray (Size: Integer): PShortArray; var p: PShortArray; begin GetMem (p, Size * SizeOf (NameStr)); AllocShortArray := p end;
{$endif}
var n:NameStr; a:PShortArray; i:integer;
begin a := AllocShortArray (3); n:='12345678'; for i:=1 to 3 do begin a^[i]:=n; writeln('n = ',n); writeln('a^[i] = ',a^[i]); end; FreeMem (a, 3 * SizeOf (NameStr)) end.
You could write a conditional wrapper for FreeMem as well, but that's not absolutely necessary since GPC ignores the 2nd parameter, anyway (it knows by itself how big the memory allocated was).
Frank
In article Pine.GSO.4.30.0107111111050.11366-100000@math, Adam Naumowicz adamn@math.uwb.edu.pl writes
But I want my sources to stay BP/Delphi compatible... I still don't know what is wrong with the getmem call. Maybe I should try this example with a newer compiler as Maurice says it works fine for him. It worked fine for me with BP, Delphi and FPC, but all those handle strings in somewhat different manner than GPC. Why is new better than getmem in this example ?
This sounds related to behaviour we have seen when using pointers to strings. In our case the problem was that the capacity field wasn't being set up correctly.
On Wed, 11 Jul 2001, Prof. A Olowofoyeku (The African Chief) wrote:
On 10 Jul 2001, at 18:24, Adam Naumowicz wrote:
Hello,
I have a basic question concerning strings and array memory representation in GPC. To my amusement I noticed that in the following program the string assigned to an array element cannot be then restored from the array itself. So probably an array of strings is not represented in memory just like an array of simple type, and cannot (?) be simply getmem-ed ?
program test; type NameStr=String[8]; shortarray=array[1..3] of NameStr;
var n:NameStr; a:^shortarray; i:integer;
begin getmem(a,3*sizeof(NameStr));
This is your problem. Use 'New' instead of 'getmem' - i.e., New (a, 3 * sizeof (NameStr)); or New (a, sizeof (shortarray)); or better still, just "New (a);"
In fact SizeOf(shortarray) is not what I really want. This example comes from a very old piece of code and of course it should be changed to a collection but it is not the point. I would like to have a pointer to an array that is large enough (up to some limit) like shortarray=array[1..30000] of NameStr; but allocate only some part of it that is really required at the moment. Regards, Adam Naumowicz
-------------------------------------- WWW: http://math.uwb.edu.pl/~adamn/ --------------------------------------
On Wed, 11 Jul 2001, Adam Naumowicz wrote:
I would like to have a pointer to an array that is large enough (up to some limit) like shortarray=array[1..30000] of NameStr; but allocate only some part of it that is really required at the moment.
Use an array of pointers to NameStr.
Then adding a new item is a simple
inc(count); shortarray[count] := new( ... shortarray[count]^ := ...
Russ