Board index » delphi » helpMe: Einvalidpointer error

helpMe: Einvalidpointer error

I use a dynamic array like
Telemet=record....end;
Parray=^Tarray;
Tarray=array[0..0] of Telement;
in my application. I want to load a dBase file and write all records into
the Telement with the "convert" procedure. My Recordcounter is
dcount:integer and my Parray is daten. 1st I get the numbe rof elements
witch are stored in the table, create then the Array. Then I call the
convert procedure, and later and that's the problem I want to give the
memory used by the Array free with freemem. But this does not work!
Compiling is ok, but during runtime the project is stopped with a invalid
pointer-operation at the FreeMem(...) line. Please help me, I can't see the
fault.

procedure Tform_main.com_convertClick(Sender: TObject);
begin
{$IFOPT R+}  {$DEFINE CKRANGE}  {$R-}{$ENDIF}
dcount:= table1.RecordCount;
getmem(daten,sizeof(Tmyelement)*dcount);
convert(daten,dcount);
FreeMem(daten,sizeof(Tmyelement)*dcount);
{$IFDEF CKRANGE}  {$UNDEF CKRANGE}  {$R+}{$ENDIF}
end;

Thank you in advance
Michael K.

 

Re:helpMe: Einvalidpointer error


Quote
Mika wrote:

> I use a dynamic array like
> Telemet=record....end;
> Parray=^Tarray;
> Tarray=array[0..0] of Telement;
> in my application. I want to load a dBase file and write all records into
> the Telement with the "convert" procedure. My Recordcounter is
> dcount:integer and my Parray is daten. 1st I get the numbe rof elements
> witch are stored in the table, create then the Array. Then I call the
> convert procedure, and later and that's the problem I want to give the
> memory used by the Array free with freemem. But this does not work!
> Compiling is ok, but during runtime the project is stopped with a invalid
> pointer-operation at the FreeMem(...) line. Please help me, I can't see the
> fault.

> procedure Tform_main.com_convertClick(Sender: TObject);
> begin
> {$IFOPT R+}  {$DEFINE CKRANGE}  {$R-}{$ENDIF}
> dcount:= table1.RecordCount;
> getmem(daten,sizeof(Tmyelement)*dcount);
> convert(daten,dcount);
> FreeMem(daten,sizeof(Tmyelement)*dcount);
> {$IFDEF CKRANGE}  {$UNDEF CKRANGE}  {$R+}{$ENDIF}
> end;

The piece of code you posted looks correct. You might check whether
'daten' has changed it's value after the call to 'convert' (only
possible if its a 'var' parameter). I would suspect the error to be
somewhere in the 'convert' routine. Do you write beyond allocated memory
there? Why not post this code too?

Two other suggestions:

1.) By defining

const
  MaxArraySize = $40000000 div SizeOf(TElement);
type
  Tarray = array[0..MaxArraySize-1] of TElement;

you can avoid having to turn of range checking.

2.) Delphi 4 has built-in support for dynamic arrays and all the pointer
allocation/deallocation is history after all. If you don't have D4 this
might be a good reason to upgrade.

Gerhard

Re:helpMe: Einvalidpointer error


I want to convert a DBase file into a file of Tmyelement, to be able to edit
this (simple) database on computers where no BDE is installed. I use
D3standart.
To your suggestions Gerhard:
1. I would not like to uses this massive memory consumtion, because the
application shell be used also on PC that are not the state of the art.
2. I don't have D4.

But I tried to change the convert proc. First I left it out and the app.
didn't crash. Then I left out filling the array with data from the DB, but
filled only .name with something like 'hello', worked as well, but all other
tries failed.

Now, the problem is still unsolved, but maybe you (all)  have some good
ideas! Thank you..

here's my definition of the dyn. array (sorry 'bout the germ. comments)

 Tmyelement=record
     name,rufname    : string[35];
     jahrgang : word;
     zug      : byte;
     n_reli,n_deutsch,n_geschichte,n_erdkunde,
     n_politik,n_englisch,n_latein,n_franz,
     n_mathe,n_physik,n_chemie,n_biologie,
     n_musik,n_kunst,n_textil,n_sport,n_diff1,
     n_diff2 : byte; //noten 1-6, 0=nicht belegt
     diff1,diff2 : string[35]; //f?chernamen
     bem1,bem2 : string[70]; // bemerkungen
     fehlstunden,unentschuldigt : word;
     versetzt : boolean;
     end;

     Pmyarray=^Tmyarray;
     Tmyarray = array[0..0] of Tmyelement;

var daten:Pmyarray;

and the convert-procedure
    procedure tform_main.convert( var dat:PmyArray; count: longint);
    var i:integer;
    begin
        table1.first;
        for i:=1 to count do
            begin

dat^[i].name:=copy(datasource1.dataset.fieldbyname('NAME').asstring,1,35);

dat^[i].rufname:=copy(datasource1.dataset.fieldbyname('RUFNAME').asstring,1,
35);
            .... // further converting from a dBase DataBase to the dyn.
array
            table1.next;
            end;
    end;

Gerhard Grosse schrieb in Nachricht <37583800.5E07E...@ph.tum.de>...

Quote

>Mika wrote:

>> I use a dynamic array like
>> Telemet=record....end;
>> Parray=^Tarray;
>> Tarray=array[0..0] of Telement;
>> in my application. I want to load a dBase file and write all records into
>> the Telement with the "convert" procedure. My Recordcounter is
>> dcount:integer and my Parray is daten. 1st I get the numbe rof elements
>> witch are stored in the table, create then the Array. Then I call the
>> convert procedure, and later and that's the problem I want to give the
>> memory used by the Array free with freemem. But this does not work!
>> Compiling is ok, but during runtime the project is stopped with a invalid
>> pointer-operation at the FreeMem(...) line. Please help me, I can't see
the
>> fault.

>> procedure Tform_main.com_convertClick(Sender: TObject);
>> begin
>> {$IFOPT R+}  {$DEFINE CKRANGE}  {$R-}{$ENDIF}
>> dcount:= table1.RecordCount;
>> getmem(daten,sizeof(Tmyelement)*dcount);
>> convert(daten,dcount);
>> FreeMem(daten,sizeof(Tmyelement)*dcount);
>> {$IFDEF CKRANGE}  {$UNDEF CKRANGE}  {$R+}{$ENDIF}
>> end;

>The piece of code you posted looks correct. You might check whether
>'daten' has changed it's value after the call to 'convert' (only
>possible if its a 'var' parameter). I would suspect the error to be
>somewhere in the 'convert' routine. Do you write beyond allocated memory
>there? Why not post this code too?

>Two other suggestions:

>1.) By defining

>const
>  MaxArraySize = $40000000 div SizeOf(TElement);
>type
>  Tarray = array[0..MaxArraySize-1] of TElement;

>you can avoid having to turn of range checking.

>2.) Delphi 4 has built-in support for dynamic arrays and all the pointer
>allocation/deallocation is history after all. If you don't have D4 this
>might be a good reason to upgrade.

>Gerhard

Re:helpMe: Einvalidpointer error


According to your type definition

Tarray=array[0..0] of Telement;

your array is zero based and you allocate memory Count elements. In your
Convert procedure the loop thus should run from 0 to Count-1. But it
runs from 1 to Count. Thus you write beyond the allocated memory range
and hence the error. Change your loop to

for i = 0 to count-1 do begin

and everything should work fine. Alternatively you can define

TArray=array[1..1] of TElement;

As to my suggestion #1: It won't take any more memory than your
solution, because you still would allocate only as much memory as
necessary. The only difference is that you don't need turn off range
checking.

Gerhard

Quote
Mika wrote:

> I want to convert a DBase file into a file of Tmyelement, to be able to edit
> this (simple) database on computers where no BDE is installed. I use
> D3standart.
> To your suggestions Gerhard:
> 1. I would not like to uses this massive memory consumtion, because the
> application shell be used also on PC that are not the state of the art.
> 2. I don't have D4.

> But I tried to change the convert proc. First I left it out and the app.
> didn't crash. Then I left out filling the array with data from the DB, but
> filled only .name with something like 'hello', worked as well, but all other
> tries failed.

> Now, the problem is still unsolved, but maybe you (all)  have some good
> ideas! Thank you..

> here's my definition of the dyn. array (sorry 'bout the germ. comments)

>  Tmyelement=record
>      name,rufname    : string[35];
>      jahrgang : word;
>      zug      : byte;
>      n_reli,n_deutsch,n_geschichte,n_erdkunde,
>      n_politik,n_englisch,n_latein,n_franz,
>      n_mathe,n_physik,n_chemie,n_biologie,
>      n_musik,n_kunst,n_textil,n_sport,n_diff1,
>      n_diff2 : byte; //noten 1-6, 0=nicht belegt
>      diff1,diff2 : string[35]; //f?chernamen
>      bem1,bem2 : string[70]; // bemerkungen
>      fehlstunden,unentschuldigt : word;
>      versetzt : boolean;
>      end;

>      Pmyarray=^Tmyarray;
>      Tmyarray = array[0..0] of Tmyelement;

> var daten:Pmyarray;

> and the convert-procedure
>     procedure tform_main.convert( var dat:PmyArray; count: longint);
>     var i:integer;
>     begin
>         table1.first;
>         for i:=1 to count do
>             begin

> dat^[i].name:=copy(datasource1.dataset.fieldbyname('NAME').asstring,1,35);

> dat^[i].rufname:=copy(datasource1.dataset.fieldbyname('RUFNAME').asstring,1,
> 35);
>             .... // further converting from a dBase DataBase to the dyn.
> array
>             table1.next;
>             end;
>     end;

Other Threads