Board index » delphi » proc. Move fails when running out of RAM !

proc. Move fails when running out of RAM !

Hi,

I came across a quite {*word*193} bug (?) in the Move procedure.

Consider the following:

type
        MyArrayType = array[0..100] of MyRecord;
        PMyArrayType = ^MyArrayType;

Now, I allocate some memory for MyArray by using GetMem:

var
        MyArray: PMyArrayType;
begin
GetMem(MyArray, Count*SizeOf(MyRecord));
        {Count is maximum 100.}
...
end;

Suppose MyRecord is that large (in bytes) that I don't have enough RAM
memory to fit MyArray into it - which can be easily simulated by allocating
an array of, say, 50 MB - then Windows will allocate the memory on the
harddisk.

Now, I need to copy the information in MyArray into a simple array of Byte
(trying to do some compression...). To do this, I used the procedure Move
as in:

Move ( MyArray, MyByteArray, Count*SizeOf(MyRecord));

This works OK for small arrays, that fit in the RAM memory, but for the big
ones, this generates seamingly random errors such as: Invalid Pointer
Operation, Divide by Zero (??? There are NO divisions in my entire
program!) or Access Violation.

Am I doing something wrong here, or is this a bug ? (Using Delphi 2, BTW)
Is there a nice way around this problem ? AFAIK, the only other way to copy
a chunk of an array is by using a for-loop, which seems to slow and more
importantly, I will always have to copy the contents of MyArray entry per
entry, but what if I need just a part of an entry ? (The compression
algoritm doesn't know anything about MyRecordType, it just reads bytes...)

TIA,

        Niels.

--------------------------------------------------------------------------
Niels Vanspauwen
Student @ KULeuven
Faculty of Civil Engineering
Department of Computer Science

E-Mail: Niels.Vanspauwen!NSPM!Student.Kuleuven.Ac.Be
(Replace !NSPM! with @ to reply...)
---------------------------------------------------------------------------

 

Re:proc. Move fails when running out of RAM !


Quote
Niels Vanspauwen wrote in message <01bd7eb0$f062e9c0$2a7a3a86@Niels>...
>I came across a quite {*word*193} bug (?) in the Move procedure.
>type
> MyArrayType = array[0..100] of MyRecord;
> PMyArrayType = ^MyArrayType;
>var
> MyArray: PMyArrayType;
>begin
>GetMem(MyArray, Count*SizeOf(MyRecord));
> {Count is maximum 100.}
>...
>end;
>Suppose MyRecord is that large (in bytes) that I don't have enough RAM
>memory to fit MyArray into it - which can be easily simulated by
allocating
>an array of, say, 50 MB - then Windows will allocate the memory on the
>harddisk.
>Now, I need to copy the information in MyArray into a simple array of
Byte
>(trying to do some compression...). To do this, I used the procedure
Move
>as in:
>Move ( MyArray, MyByteArray, Count*SizeOf(MyRecord));

You mis-interpreted the docs. Use the procedure like:

move(MyArray^, MyByteArray, Count * SizeOf(MyRecord));
You may also need MyByteArray^, depending on the declaration

Quote
>This works OK for small arrays, that fit in the RAM memory, but for the
big
>ones, this generates seamingly random errors such as: Invalid Pointer
>Operation, Divide by Zero (??? There are NO divisions in my entire
>program!) or Access Violation.

Your code thrashes the stack (assuming MyArray was a local variable),
and probably the return address was altered.

Quote
>Am I doing something wrong here, or is this a bug ? (Using Delphi 2,
BTW)
>Is there a nice way around this problem ? AFAIK, the only other way to
copy
>a chunk of an array is by using a for-loop, which seems to slow and
more
>importantly, I will always have to copy the contents of MyArray entry
per
>entry, but what if I need just a part of an entry ? (The compression
>algoritm doesn't know anything about MyRecordType, it just reads

bytes...)

As you realize by now, move() passes the values by reference, so you
need to de-reference your pointers. The Windows implementation (named
CopyMemory) has a more natural interface.

Also take a look at the functions IsBadReadPointer and
IsBadWritePointer.
--
Zweitze de Vries
zweitze<at>iname<dot>com
When replying, please adjust reply address

Re:proc. Move fails when running out of RAM !


Quote

> >Move ( MyArray, MyByteArray, Count*SizeOf(MyRecord));

> You mis-interpreted the docs. Use the procedure like:

> move(MyArray^, MyByteArray, Count * SizeOf(MyRecord));
> You may also need MyByteArray^, depending on the declaration

Sorry, I made a mistake in my posting !! I _DO_ dereference the pointers as
you suggest, but as said, this causes major problems with large memory
blocks.

Quote
> As you realize by now, move() passes the values by reference, so you
> need to de-reference your pointers. The Windows implementation (named
> CopyMemory) has a more natural interface.

Yes, but Delphi translates the CopyMemory (and also MoveMemory etc.) into
Move procedure calls, so no help there I'm afraid.

--------------------------------------------------------------------------
Niels Vanspauwen
Student @ KULeuven
Faculty of Civil Engineering
Department of Computer Science

E-Mail: Niels.Vanspauwen!NSPM!Student.Kuleuven.Ac.Be
(Replace !NSPM! with @ to reply...)
---------------------------------------------------------------------------

Other Threads