• 给数据指针分配内存


     对静态数组指针, 虽然在声明之处并没有分配内存, 但这个指针应该分配多少内存是有定数的.

    这种情况, 我们应该用 New 和 Dispose 来分配与释放内存. 譬如:
    type
      TArr1 = array[0..255] of Char;
      TArr2 = array[0..255] of Integer;
    var
      arr1: ^TArr1;
      arr2: ^TArr2;
    begin
      New(arr1);
      New(arr2);
    
      arr1^ := '万一的 Delphi 博客';
      ShowMessageFmt('%s%s', [arr1^[0], arr1^[1]]); {万一}
    //  ShowMessageFmt('%s%s', [arr1[0], arr1[1]]); {这样也可以}
    
      arr2[Low(arr2^)] := Low(Integer); {第一个元素赋最小值}
      arr2[High(arr2^)] := MaxInt;      {第一个元素赋最大值}
      ShowMessageFmt('%d, %d', [arr2[0], arr2[255]]); {-2147483648, 2147483647}
    
      Dispose(arr1);
      Dispose(arr2);
    end;
    
    给已知大小的指针分配内存应该用 New, 上面的例子是关于静态数组指针的, 后面要提到的结构体(记录)的指针也是如此.

    New 的本质也函数调用 GetMem, 但不需要我们指定大小了.
    那怎么给动态数组的指针分配内存呢? 其实动态数组变量本身就是个指针, 就不要绕来绕去再给它弄指针了.

    不过有一个理念还是满重要的, 那就是我们可以把一个无类型指针转换为动态数组类型, 譬如:
    type
      TArr = array of Integer;
    var
      p: Pointer;
    begin
      GetMemory(p, 3 * SizeOf(Integer)); {分配能容纳 3 个 Integer 的空间}
    
      {这和 3 个元素的 TArr 的大小是一样的, 但使用时需要进行类型转换}
      TArr(p)[0] := Random(100);
      TArr(p)[1] := Random(100);
      TArr(p)[2] := Random(100);
    
      ShowMessageFmt('%d,%d,%d', [TArr(p)[0], TArr(p)[1], TArr(p)[2]]); {0,3,86}
    
      FreeMemory(p);
    end;
    

    这里用到了 GetMemory 和 FreeMemory, 对分配无类型指针这是比较常用的
     
    先总结下: 
    New 是给已知大小的指针分配内存;
    GetMem 主要是给无类型指针分配内存;
    尽量使用 GetMemory 来代替 GetMem.

    还有个 AllocMem 和它们又有什么区别呢?

    AllocMem 分配内存后会同时初始化(为空), GetMem 则不会, 先验证下:
    var
      p1,p2: Pointer;
    begin
      p1 := AllocMem(256);
      ShowMessage(PChar(p1)); {这里会显示为空}
      FreeMemory(p1);
    
      p2 := GetMemory(256);
      ShowMessage(PChar(p2)); {这里会显示一些垃圾数据, 内容取决与在分配以前该地址的内容}
      FreeMemory(p2);
    end;
    
    关于 FreeMemory 与 FreeMem 的区别:
    1、FreeMemory 会检查是否为 nil 再 FreeMem, 这有点类似: Free 与 Destroy;
    2、FreeMem 还有个默认参数可以指定要释放的内存大小, 不指定就全部释放(没必要只释放一部分吧);
    3、New 对应的 Dispose 也可以用 FreeMem 或 FreeMemory 代替.

    尽量使用 FreeMemory 来释放 GetMem、GetMemory、AllocMem、ReallocMem、ReallocMemory 分配的内存.

    ReallocMem、ReallocMemory 是在已分配的内存的基础上重新分配内存, 它俩差不多 ReallocMemory 比 ReallocMem 多一个 nil 判断, 尽量使用 ReallocMemory 吧. 譬如:
    type
      TArr = array[0..MaxListSize] of Char;
      PArr = ^TArr;
    var
      arr: PArr;
      i: Integer;
    begin
      arr := GetMemory(5);
      for i := 0 to 4 do arr[i] := Chr(65+i);
      ShowMessage(PChar(arr)); {ABCDE}
    
      arr := ReallocMemory(arr, 26);
      ShowMessage(PChar(arr)); {ABCDE}
      for i := 0 to 25 do arr[i] := Chr(65+i);
      ShowMessage(PChar(arr)); {ABCDEFGHIJKLMNOPQRSTUVWXYZ}
    end;
    
     
     
     
  • 相关阅读:
    python 获取Excel 的内容
    python 获取文件Excel 的行数与列数
    python 读取Excel 取出表头(列名)
    DRF的视图组件
    Redis
    Git的故事
    DRF的JWT用户认证
    DRF的三大认证组件
    DRF的序列化组件
    DRF的请求响应组件
  • 原文地址:https://www.cnblogs.com/hnxxcxg/p/2940796.html
Copyright © 2020-2023  润新知