Newsgroup: it.comp.lang.delphi
Titolo: Incomprensibile problema con i puntatori.

Salve,
ecco uno di quei casi in cui ottengo comportamenti che non comprendo.
Il codice incriminato completo di numero di riga:
01 | Procedure TForm1.Button1Click (Sender: TObject);
02 | Var p1 :Pointer;
03 | p2 :Array Of Integer;
04 | I :Integer;
05 | Begin
06 | GetMem (p1, 1000);
07 | p2:=p1;
08 | For I:=0 To 249 Do ListBox1.Items.Add (IntToStr(p2[I]));
09 | FreeMem (p1, 1000);
10 | End;
Tutto funziona a meraviglia fino alla riga 8 (compresa). All'esecuzione
della riga 9 ottengo un'eccezione EInvalidPointer.
Togliendo la riga 9 il comportamento e' lo stesso: EInvalidPointer.
Sostituendo la riga 9 con FreeMem (p2, 1000) il comportamento continua ad
essere lo stesso: EInvalidPointer.
Questo tipo di operazione fra puntatori mi sarebbe comoda in un mio
componente ma come evitare l'eccezione? E' evitabile? Abbandono questo
approccio?
Ciao
   Jenner
--------------------------------
Inviato via 
http://usenet.libero.it


Ciao.
Giuseppe

 Oppure cambi il codice in questo modo:
[codice]
No, non posso fare cosi'.
Ho bisogno di accedere ai dati puntati dal tipo Pointer con vari tipi di
array dinamici (quello ad Integer e' un esempio) a mo di diversi
"interfacciamenti" e conservando la comodita' dell'accesso vettoriale (non
mi piace fare avanti e indietro con le Inc() e Dec() sui PChar...).



    Via De Gasperi, 14 - 42019
    Scandiano (Reggio Emilia)

 > Potresti provare così:


 ha scritto nel messaggio
news:GqYba.50065$pG1.1...@news1.tin.it...


Insomma, non si capisce bene cosa vuoi ottenere dal tuo codice.
Spero che ora sia piu' chiaro...


 10 | End;
Premettendo che mi sembra un codice confuso e che mischiare tecniche diverse
mi fa pensare a cattiva programmazione.
Perchč assegni a P2 (che č un array dinamico) il puntatore P1?? E' tutto lě
il problema di quel codice.
Quale č lo scopo? mostrare a video il contenuto di una area di memoria??
Ciao
Matteo

zone di memoria contigue come tutti gli altri... 
No, non lo sono.  Benché sono gestiti come puntatori, in realtà
subiscono dei meccanismi particolari (come il copy-on-write e il
reference counting delle stringhe) a cui i normali puntatori non sono
soggetti.
-- 
Andrea Laforgia
Gioca a Tetris !
http://www.geocities.com/andrealaforgia/downloads.html

 Function TMioOggetto.GetElement (pIndex :Integer) :Integer;
...
Che ne dici di questo (v. sotto)?
Saluti
Paolo Arosio
unit uFalseSimpleTypeArray;
interface
uses SysUtils, Classes;
type
  EFSTArray = class(Exception);
  TFalseSimpleTypeArray = class
  private
    fStream: TMemoryStream;
    FCurrentElementSize: integer;
    procedure SetCurrentElementSize(const Value: integer);
    function GetCount: integer;
    function GetIntegers(Index: integer): Integer;
    procedure SetIntegers(Index: integer; const Value: Integer);
    function GetBytes(Index: integer): Byte;
    procedure SetBytes(Index: integer; const Value: Byte);
  public
    constructor Create(ElementSize, InitialCount: integer);
    destructor Destroy; override;
    property CurrentElementSize: integer read FCurrentElementSize write
SetCurrentElementSize;
    property Count: integer read GetCount;
    property Integers[Index: integer]: Integer read GetIntegers write
SetIntegers;
    property Bytes[Index: integer]: Byte read GetBytes write SetBytes;
  end;
implementation
{ TFalseSimpleTypeArray }
constructor TFalseSimpleTypeArray.Create(ElementSize,
  InitialCount: integer);
begin
  fStream := TMemoryStream.Create;
  if ElementSize = 0 then
    ElementSize := Sizeof(Integer);
  fCurrentElementSize := ElementSize;
  fStream.SetSize(fCurrentElementSize * InitialCount);
end;
destructor TFalseSimpleTypeArray.Destroy;
begin
  fStream.Free;
  inherited;
end;
function TFalseSimpleTypeArray.GetCount: integer;
begin
  Result := fStream.Size div FCurrentElementSize;
end;
procedure TFalseSimpleTypeArray.SetCurrentElementSize(
  const Value: integer);
var NewSize: Int64;
begin
  NewSize := fStream.Size;
  while (NewSize mod Value <> 0) do
    Inc(NewSize);
  if NewSize <> fStream.Size then
    fStream.SetSize(NewSize);
  FCurrentElementSize := Value;
end;
function TFalseSimpleTypeArray.GetIntegers(Index: integer): Integer;
var ps: Int64;
begin
  if Index < 0 then
    raise EFSTArray.Create('Index out of bounds: ' + inttostr(Index));
  SetCurrentElementSize(Sizeof(Result));
  if Index >= Count then
    raise EFSTArray.Create('Index out of bounds: ' + inttostr(Index));
  ps := Index * CurrentElementSize;
  fStream.Seek(ps, soFromBeginning);
  if fStream.Read(Result, CurrentElementSize) < CurrentElementSize then
    raise EFSTArray.Create('Read error');
end;
procedure TFalseSimpleTypeArray.SetIntegers(Index: integer;
  const Value: Integer);
var ps: Int64;
begin
  if Index < 0 then
    raise EFSTArray.Create('Index out of bounds: ' + inttostr(Index));
  SetCurrentElementSize(Sizeof(Value));
  if Index > Count then begin
    fStream.SetSize(Index * CurrentElementSize); // automatic grow
    // raise EFSTArray.Create('Index out of bounds: ' +
inttostr(Index));
  end;
  ps := Index * CurrentElementSize;
  fStream.Seek(ps, soFromBeginning);
  if fStream.Write(Value, CurrentElementSize) < CurrentElementSize then
    raise EFSTArray.Create('Write error');
end;
function TFalseSimpleTypeArray.GetBytes(Index: integer): Byte;
begin
  if Index < 0 then
    raise EFSTArray.Create('Index out of bounds: ' + inttostr(Index));
  SetCurrentElementSize(Sizeof(Result));
  if Index >= Count then
    raise EFSTArray.Create('Index out of bounds: ' + inttostr(Index));
  fStream.Seek(Index, soFromBeginning);
  if fStream.Read(Result, CurrentElementSize) < CurrentElementSize then
    raise EFSTArray.Create('Read error');
end;
procedure TFalseSimpleTypeArray.SetBytes(Index: integer;
  const Value: Byte);
begin
  if Index < 0 then
    raise EFSTArray.Create('Index out of bounds: ' + inttostr(Index));
  SetCurrentElementSize(Sizeof(Value));
  if Index > Count then begin
    fStream.SetSize(Index * CurrentElementSize); // automatic grow
    // raise EFSTArray.Create('Index out of bounds: ' +
inttostr(Index));
  end;
  fStream.Seek(Index, soFromBeginning);
  if fStream.Write(Value, CurrentElementSize) < CurrentElementSize then
    raise EFSTArray.Create('Write error');
end;
end.