Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Asignar memoria (https://www.clubdelphi.com/foros/showthread.php?t=88243)

doctorhd 06-05-2015 06:54:51

Asignar memoria
 
Holas, tengo la siguiente duda, he creado un record con la siguiente estructura:
Código Delphi [-]
type
    TClaveValor = record
    private
      FClave:string;
      FValueDefault:Variant;
      FValue:Variant;
      FTipo:TEnumTypeData;
      procedure SetClave(const Value:string);
      procedure SetValueDefault(const Value:variant);
      procedure SetValue(const Value:variant);
      procedure SetTipo(const Value:TEnumTypeData);
    public
      property Clave: string read FClave write SetClave;
      property ValueDefault: Variant read FValueDefault write SetValueDefault;
      property Value:Variant read FValue write SetValue;
      property Tipo: TEnumTypeData read FTipo write SetTipo;
    end;
A su vez he creado un tipo que apunta a dicho record:
Código Delphi [-]
type PClaveValor = ^TClaveValor;{Puntero a TClaveValor}
Estas estructuras las utilizo para crear elementos en otra clase:
Código Delphi [-]
type ArrayPClaveValor = array of PClaveValor;{array de punteros a PClaveValor}

type
    TParamRegWin = class
    private
      FParams:ArrayPClaveValor;
      function getParam(const Index: Integer): PClaveValor;
      procedure setParam(const Index: Integer; const Value: PClaveValor);
      function getCount:Integer;
      ....
    public
      constructor Create;
      destructor Destroy; override;
      procedure AddParam(const AClave:string; const AValueDefault:Variant;AValue:Variant; const ATipo:TEnumTypeData);
      ....
    public
      property Param[const Index: Integer]:PClaveValor read getParam write setParam;
      property Params:ArrayPClaveValor read FParams write FParams;
      property Count:Integer read getCount;
    end;
El problema se suscita al crear un nuevo elemento, el cual lo realizo en el procedure AddParam:
Código Delphi [-]
procedure TParamRegWin.AddParam(const AClave:string; const AValueDefault:Variant;AValue:Variant; const ATipo:TEnumTypeData);
  var vElementos:integer; vPParam:PClaveValor;
  begin
    vElementos:=Length(FParams);
    Setlength(FParams,vElementos+1);{Dimencionamos el tamaño de la lista de campos}
    New(vPParam);
    vPParam.Clave:=AClave;
    vPParam.ValueDefault:=AValueDefault;
    vPParam.Value:=AValue;
    vPParam.Tipo:=ATipo;
    FParams[vElementos]:=vPParam;
  end;{procedure}
Como veran utilizo el comando NEW para asignar la memoria al nuevo objeto, el cual cumple su función, pero antes de llegar a utilizar New utilice:
Código Delphi [-]
vPParam:=System.AllocMem(SizeOf(TClaveData));
Pero su utilización hacia que se borrara parte del contenido de variables que no participaban dentro del procedure, también probé:
Código Delphi [-]
GetMen(vPParam,SizeOf(TClaveData));
Pero también tuve problemas, en la asignación de los valores al puntero.
Mi pregunta es AllocMem y GetMen hacen asignación de memoria disponible o asignan memoria de la que primero encuentran, ya que de acuerdo a las pruebas realizadas, ambos métodos interfieren con la memoria utilizada por otras variables o componentes asignados con anterioridad....Y por ultimo que diferencia existe entre estos dos métodos y el comando NEW...

Saludos....

ecfisa 06-05-2015 10:12:20

Hola doctorhd.
Cita:

Empezado por doctorhd (Mensaje 491919)
...
Mi pregunta es AllocMem y GetMen hacen asignación de memoria disponible o asignan memoria de la que primero encuentran, ya que de acuerdo a las pruebas realizadas, ambos métodos interfieren con la memoria utilizada por otras variables o componentes asignados con anterioridad....Y por ultimo que diferencia existe entre estos dos métodos y el comando NEW...

Saludos....

AllocMem y GetMem hacen uso, de ser posible, de la memoria disponible en el heap. No utilizan la primera memoria que encuentran, de otro modo su uso sería un tormento y el autor un perverso. :)

La diferencia entre la función AllocMem y el procedimiento GetMem es que el primero inicializa la memoria asignada y el segundo no. Debido a esto último GetMem es mas eficiente en velocidad (pero a veces es necesaria la inicializacion).

New difiere de los anteriores en que no es necesario indicarle el tamaño a de memoria a asignar, pero no puede manejar un tamaño arbitrario de memoria.

Unos ejemplos muy sencillos de cada uno:
Código Delphi [-]
// AllocMem
var
  buffer: PChar;
  s     : string;
begin
  s := 'usando AllocMem'+#0;
  try
    // AllocMem inicializa la memoria asignada con ceros 0
    buffer  := AllocMem(Length(s));
    ShowMessage(buffer);  // cadena vacia
    StrPCopy(buffer, s);
    ShowMessage(buffer);
  finally
    FreeMem(buffer);
  end;
end;

// GetMem
var
  buffer: PChar;
  s     : string;
begin
  s := 'usando GetMem'+#0;
  try
    // GetMem no inicializa la memoria asignada
    GetMem(buffer, Length(s));
    ShowMessage(buffer);  // basura
    StrPCopy(buffer, s);
    ShowMessage(buffer);
  finally
    FreeMem(buffer);
  end;
end;


// New
procedure TForm1.btnNewClick(Sender: TObject);
type
  PReg = ^TReg;
  TReg = record
    dato1: PChar;
    dato2: Integer;
    //...
  end;
var
  pr: PReg;
  s : string;
begin
  s := 'usando New'+#0;
  pr := nil;
  try
    // New no inicializa la memoria asignada
    New(pr);
    ShowMessage(Format('%s %d',[pr.dato1, pr.dato2])); // basura
    GetMem(pr.dato1, Length(s));
    StrPCopy(pr.dato1,s);
    pr.dato2 := 1397;
    ShowMessage(Format('%s %d',[pr.dato1, pr.dato2]));
  finally
    FreeMem(pr.dato1);
    Dispose(pr);
  end;
end;

Saludos :)

nlsgarcia 06-05-2015 10:18:54

doctorhd,

Cita:

Empezado por doctorhd
...¿AllocMem y GetMen hacen asignación de memoria disponible o asignan memoria de la que primero encuentran?...

:rolleyes:

AllocMem, GetMen y New solo asignan bloques de memoria que estén disponibles, en caso de no encontrar la memoria requerida, ocurre una excepción de tipo EOutOfMemory pero en ningún caso se sobrescriben bloques de memoria que estén siendo utilizados.

Revisa esta información
Espero sea útil :)

Nelson.


La franja horaria es GMT +2. Ahora son las 04:47:13.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi