Jump to content
milurt

memory paging or segmentation

Recommended Posts

if i use getmem's it seems that i need memory paging or segmentation to get the values.

can somebody explain an asm,c,delphi source, that is usable like

number=Pointer1^;

 

Share this post


Link to post

If you get a segmentation violation or something, you are doing something that is not allowed. Show some code.

Share this post


Link to post
17 hours ago, milurt said:

if i use getmem's it seems that i need memory paging or segmentation to get the values.

can somebody explain an asm,c,delphi source, that is usable like

number=Pointer1^;

 

In Delphi you very rarely need to go as far down to the metal as GetMem. If you need arrays of some element type and don't know the size needed at coding time use a dynamic array type. Once your code has figured out the size needed use SetLength on the array to allocate the needed memory for it, then access members of the array with the classical array syntax ([index]). For array of characters use the String type in the same manner. This way you never have to deal with raw memory allocation or pointer manipulation (where you better know what you are doing if you value your sanity).

You can use pointer stuff in Delphi if you really need to, but there is rarely any need. If you need a pointer to pass to some low-level API the @ operator is your friend, you can allocate memory using a dynamic array and then pass @A[0] (the address of the first array element) as the pointer. Just be aware that this only works for one-dimensional arrays. Multidimensional dynamic arrays do not occupy one single memory block. Refer to the Delphi Language Guide to learn about such pesky details, it is part of the main online help.

 

Oh, to get a value a pointer points at you best use a specific pointer type that defines the type of data the pointer points at, e.g you use a PInteger (defined as

type PInteger = ^Integer;

 in the run-time library units, System.Types I think) in preference to the raw Pointer type if you know the pointer points at an integer (or an array of integers). You can then just dereference the pointer to get the pointed-at value into an integer variable:

var
  N: Integer;
  P: PInteger;
begin
  ...assign an address to P
  N:= P^;

If you only have a raw pointer you can typecast it to the specific pointer type for the assignment.

var
  N: integer;
  P: Pointer
begin
  ...asign an address to P
  N:= PInteger(P)^;

 

Share this post


Link to post

var ballnumber:^BYTE;

Begin
  GetMem(ballnumber,70000);
  For i:=0 to 70000
  do begin ballnumber^:=5;ballnumber:=ballnumber+1;
End;
End.

at the next SEGM:0000 which will be written is a
runtime error

 

Share this post


Link to post
17 hours ago, milurt said:

var ballnumber:^BYTE;

Begin
  GetMem(ballnumber,70000);
  For i:=0 to 70000
  do begin ballnumber^:=5;ballnumber:=ballnumber+1;
End;
End.

at the next SEGM:0000 which will be written is a
runtime error

 

Which OS/CPU are we talking about here? What you show has not been a problem since 16-bit (DOS, Win 2.x, 3.x) programs have gone the way of the dinosaurs. 32 and 64 bit CPUs use a different memory architecture. 32 bit CPUs (Intel) do in fact still have segment registers but their content is constant during normal program runs, and the offset (address) registers are 32 bit wide, so a memory block can be up to 4GB large in theory. Due to OS requirement (Windows) 32 bit application programs can only use 2GByte of this theoretical address space though (3GByte with a special executable flag).

Share this post


Link to post

i really do not have to write 1000  0s that is 64 bit.

i program in embarcadero 10.3  windows 10

 

Share this post


Link to post

You are still trying to write 70001 entries (0 to 70000) into a 70000-byte array. That it reports an error when you pass the end is the expected result.

Share this post


Link to post

As @PeterBelow wrote to you, what you indicated can be written more simply, readably and effectively in Pascal. It looks like you're writing "C" code.

Just in case, to explain better you can write this code which allows you to:

1) In case of fixed extensions, to avoid some errors because they are already checked during compilation;

2) However, in case of errors (as in dynamic extensions), much clearer errors will be generated (erange errror: "Range Check Error");

3) You can use the Low, High methods to automatically limit the cycles to the maximum extent of the arrays, avoiding the risk of "overshooting" the limits.

 

//Static array

var ballnumber: array [0..6999] of byte;
    i: integer;
begin
  for i := Low(ballnumber) to High(ballnumber) do
    ballnumber[i] := 5;
end;

//Dynamic array

var ballnumber: array of byte;
    i: integer;
begin
  try
    SetLength(ballnumber, 7000);             //<----Like GetMem
    for i := Low(ballnumber) to High(ballnumber) do
      ballnumber[i] := 5;
  finally
    SetLength(ballnumber, 0);               //<---- Like FreeMem
  end;
end;

 

Edited by DelphiUdIT
  • Like 1

Share this post


Link to post

i do not need efficience code. i have the problem that there is a runtime error at segm:0000 and segm:0001

Share this post


Link to post

@milurt As timfrost wrote

On 3/4/2023 at 10:58 PM, timfrost said:

You are still trying to write 70001 entries (0 to 70000) into a 70000-byte array. That it reports an error when you pass the end is the expected result.

Your exception happens because you go from 0 to 70000 instead of 0 to 69999.

Share this post


Link to post

How many items in this list:

 

  • 0
  • 1
  • 2
  • 3

I think there are four items in this list, but the logic in your code would conclude that there are three items in this list. Therein lies your problem.

 

Of course your real code may be completely different to the code you showed us in which case who knows what's wrong with it.

Share this post


Link to post

you want to say getmem gives a pointer to segm:0000,

can you not write for i:=1 and accept that the problem is

ballnumber:=59; if ballpointer=each segm:0000 or segm:0001

 

Share this post


Link to post
On 3/7/2023 at 1:24 PM, David Heffernan said:

How many items in this list:

 

  • 0
  • 1
  • 2
  • 3

@milurt Is this question too hard for you to answer?

 

I think that the answer is 4, but you seem to think that the answer is 3.

Share this post


Link to post

david heffernan,

if it is so important, i wrote, that you can write for i:=1 to

 

and i sayed the problem is segm:0000^=83; gave a runtime error.

and i wanted to know about paging and segmentation.

 

lars fosdal,

i meant ballnumber^:=59 if ballnumber=each segm:0000 or segm:0001

gave the runtime error

 

 

Share this post


Link to post

You don't need to know about paging or segmentation. You need to learn how to allocate memory and then only access addresses within the memory that you allocated. 

Share this post


Link to post

You should post a real demo that we can compile where you get that kind of error.  When it's correctly you can not get thet runtime error.

Share this post


Link to post
15 hours ago, milurt said:

but i get always the runtime error on ballnumber=segm:0000

 

There's a bug in your code. It surprise you to learn that we can't see your screen. 

Share this post


Link to post

When you use getmem, in general, you are given a virtual memory address expressed in this form:

xxxx:0, whose length depends on how many bytes you allocate.

If for example if you allocate 1000 bytes it will be:

xxxx:0 - xxxx:999

Where xxxx is called segment.

If you try to use xxxx:1000 you exit the memory segment and the segm "segment" error is thrown.
This is a HARDWARE protection mechanism and you can do nothing to avoid it.

I repeat, avoid using the logic of the "C" language and use the form and rules of "Pascal", they will help you avoid these errors.

HI.

Share this post


Link to post
4 hours ago, DelphiUdIT said:

When you use getmem, in general, you are given a virtual memory address expressed in this form:

xxxx:0, whose length depends on how many bytes you allocate.

If for example if you allocate 1000 bytes it will be:

xxxx:0 - xxxx:999

Where xxxx is called segment.

If you try to use xxxx:1000 you exit the memory segment and the segm "segment" error is thrown.
This is a HARDWARE protection mechanism and you can do nothing to avoid it.

I repeat, avoid using the logic of the "C" language and use the form and rules of "Pascal", they will help you avoid these errors.

HI.

There's really no significant difference here between C and Pascal. 

Share this post


Link to post

now compile it:

 

program Memorial;

  {$APPTYPE GUI}

  var ballpointer,step:pchar;
    a:NativeInt;

Begin
  step:=ptr(1);
  ballpointer:=GetMemory(3000000);
  for a:=1 to 3000000 do
  begin
    ballpointer^:=#45;
    ballpointer:=ballpointer+1;
  end;
end.

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×