tags:

views:

303

answers:

3

How can i rewrite this C++ code in Delphi?

int *intim = new int[imsize];
unsigned char *grays = new unsigned char[imsize];
int *intim2 = intim;

How can I increment pointer like this:

*(intim++) = x;
+6  A: 

In Delphi you can use pointers (like in C/C++) but usually you try to avoid it.

the code looks most like

uses
  Types;

procedure Test();
var
  intim: TIntegerDynArray;
  grays: TByteDynArray;
  P:     PInteger;
  i, s:  Integer;
begin
  // 'allocate' the array
  SetLength(intim, imsize);
  SetLength(grays, imsize);

  // if you want to walk through the array (Delphi style)
  for i := Low(intim) to High(intim) do intim[i] := GetValueFromFunction();
  // or (read only access, sum the array)
  s := 0;
  for i in intim do Inc( s, i );
  // or with pointers:
  P := @intim[ 0 ];
  for i := 0 to High(intim) do begin
    P^ := x;
    Inc( P ); // like P++;
  end;
end; 
Ritsaert Hornstra
Instead of using :=0 to High(xxx) you should use :=Low(xxx) to High(xxx)If you get used to this, you won't ever run into trouble if you suddenly encounter an array defined as [10..20] of Integer.So - get used to using both Low and High - it'll pay off in the end...
HeartWare
@heartware: you are right, I am used to our strict policy never to use anything other than zero-based arrays. As a warning to Kowalikus: arrays are not always zero based! Dynamic arrays (as in the example above) are always zero based. Strings however are 1-based for compatibility with archaic Pascal versions from the previous century.
Ritsaert Hornstra
+2  A: 

The best way would be to use arrays. If imsize is a constant, you want a static array, otherwise, you'll use a dynamic array. Here's the syntax for both:

Static:

var
  intim: array[0..imsize - 1] of integer;

Dynamic:

var
  intim: array of integer;
begin
  setLength(intim, imsize);
  //do something with intim
end;

As for grays, how you'll declare it depends on if you're using your array of "unsigned chars" as characters (a string) or as single-byte integers. If they're integers, you can declare an unsigned single-byte integer as byte, and declare an array (either static or dynamic) of them using the syntax described above. If they're characters, just use the string type.

And the pointer math is possible, but not recommended because it makes buffer overruns too easy. Instead, try declaring your other variable as an integer and use it as an index into the array. If you have bounds checking turned on, this will prevent you from going beyond the end of the array and corrupting memory.

Mason Wheeler
+2  A: 

The people who point out that you should use array types rather than a direct pointer manipulation done as you see it done above in C, are right, it is not idiomatic to Delphi to use dangerous pointer types when safe arrays are easier, can be verified faster, and are safer at runtime. However for the pedantic out there who want to avoid using the nice built in array types, it is possible, albeit stupid, to do so:

var
 intim,intim2:PInteger;
 x:Integer;
begin
  x := 0;
  intim := AllocMem(SizeOf(Integer)*imsize);
  intim2 := intim;
//  dereference pointer intim2, store something, then increment pointer
  intim2^ := x;
  Inc(intim2);

  FreeMem(intim);
Warren P
The first time I posted this code, it allocated memory, stored and then incremented, and then freed a different pointer than the one I received back from the allocator. That could be bad. (Fixed!)
Warren P