Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2012-06

Accessing open array

5 messages · 3 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Koenraad Lelong

Hi,

Im trying to access an open array but I get a runtime error. I googled a bit, and found some suggestions, but for me they don't work. It's actually a port of some C-library I want to use on a STM32-processor.

This is my test-code :

program LCDtest1;
type
  TArray = array of byte;
var
  nCols : cardinal;
  nRows : cardinal;
  nBytes : cardinal;
  pFont : ^TArray;
{$include fonts.inc}
begin
// get pointer to the beginning of the selected font table
;
writeln('0');
setlength(pFont^,8);  <-- here it crashes
writeln('1');
nCols:=pFont^[0];
//nCols:=pFont^[low(pFont^)];
{writeln('2');
nRows:=pFont^[1];
writeln('3');
nBytes:=pFont^[2];}
writeln('end');
end.
I didn't have the setlength at first, then it crashed at the first
access of the array (ncols:=...).

The include file contains this (only partly shown) :

originally :

const
FONT6x8 : array[0..96] of array[0..7] of byte = (
($06,$08,$08,$00,$00,$00,$00,$00), // columns, rows, num_bytes_per_char ($00,$00,$00,$00,$00,$00,$00,$00), // space $20
($20,$20,$20,$20,$20,$00,$20,$00), // !
($50,$50,$50,$00,$00,$00,$00,$00), // "
($50,$50,$F8,$50,$F8,$50,$50,$00), // #
...

modified (with the same error) :

const
FONT6x8 : array[0..775] of byte = (
($06,$08,$08,$00,$00,$00,$00,$00, // columns, rows, num_bytes_per_char ($00,$00,$00,$00,$00,$00,$00,$00, // space $20
($20,$20,$20,$20,$20,$00,$20,$00, // !
($50,$50,$50,$00,$00,$00,$00,$00, // "
($50,$50,$F8,$50,$F8,$50,$50,$00, // #
...

Any suggestions how I can correct my code ?

Thanks,

Koenraad Lelong.

Koenraad Lelong
to Koenraad Lelong
Koenraad Lelong wrote
Hi, Im trying to access an open array but I get a runtime error. I googled a bit, and found some suggestions, but for me they don't work.

Forgot to say : runtime error is 216.

Show quoted text 10 lines
modified (with the same error) : const FONT6x8 : array[0..775] of byte = ( $06,$08,$08,$00,$00,$00,$00,$00, // columns, rows, num_bytes_per_char $00,$00,$00,$00,$00,$00,$00,$00, // space $20 $20,$20,$20,$20,$20,$00,$20,$00, // ! $50,$50,$50,$00,$00,$00,$00,$00, // " $50,$50,$F8,$50,$F8,$50,$50,$00, // # ...

This is my actual code.

Koenraad Lelong.

Jonas Maebe
to Koenraad Lelong: Im trying to access an open array but I get a runtime error. I googled a bit, and found…
Koenraad Lelong wrote
Im trying to access an open array but I get a runtime error.

You are trying to use a pointer to a static array as a pointer to a dynamic array (not an open array; have a ://rvelthuis.de/articles/articles-openarr.html to read about the differences between all the kinds of array types).

It's normal that this crashes. A static array is something completely different than a dynamic array. If you add {$T+} to your source code (to enable typed pointers), the compiler will tell you that those pointer types are incompatible.

Any suggestions how I can correct my code ?

It is not possible to declare an initialized dynamic array. You have to initialize it dynamically, e.g. via

var
  arr: tarray;
begin
  setlength(arr,8);
  move(FONT6x8[low(FONT6x8)],arr[low(arr)],8);
end;

Note: the extra [low(arr)] is required for the dynamic array (because a dynamic array is an implicit pointer, and without the [low(arr)] you will start overwriting that implicit pointer itself, along with everything coming after it in memory). It's not required for the static array, but it's good practice to always write it in order to avoid getting nasty bugs when changing the type of the array later on for some reason. And using low() rather than 0 protects you in case the lower bound of the array changes for some reason.

Jonas

Mark Morgan Lloyd
to Koenraad Lelong: Im trying to access an open array but I get a runtime error. I googled a bit, and found…
Koenraad Lelong wrote 37 lines
Hi, Im trying to access an open array but I get a runtime error. I googled a bit, and found some suggestions, but for me they don't work. It's actually a port of some C-library I want to use on a STM32-processor. This is my test-code : program LCDtest1; type TArray = array of byte; var nCols : cardinal; nRows : cardinal; nBytes : cardinal; pFont : ^TArray; {$include fonts.inc} begin // get pointer to the beginning of the selected font table ; writeln('0'); setlength(pFont^,8); <-- here it crashes I didn't have the setlength at first, then it crashed at the first access of the array (ncols:=...). The include file contains this (only partly shown) : originally : const FONT6x8 : array[0..96] of array[0..7] of byte = (

Assuming that in your current implementation FONT6x8 is a table at an absolute location in memory... I don't think you can do that, since a dynamic array (which I think is what you're trying to use) is nowt but a descriptor block which contains a pointer into the heap. Try something like

type	TFONT6x8= array[0..96] of array[0..7] of byte;
	PFONT6x8= ^TFONT6x8;
var	fontTable: PFONT6x8;

Force your absolute address into fontTable, then dereference to get at the content.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]
Koenraad Lelong
to Mark Morgan Lloyd

Hi,

Looking at the C-code again, I saw I could actually use a pointer to byte, instead of a pointer to an array of bytes.
So I'm using this :

program LCDtest1;
var
  nCols : cardinal;
  nRows : cardinal;
  nBytes : cardinal;
  pFont : ^byte;
{$include fonts.inc}
begin
// get pointer to the beginning of the selected font table
;
nCols:=pFont^;
nRows:=(pFont+1)^;
nBytes:=(pFont+2)^;
end.

Now my library works.

Thanks,

Koenraad Lelong.