Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我正在尝试在Delphi函数中使用和释放2个指针。我如何正确地释放它们?_Delphi_Pointers_Delphi Xe3 - Fatal编程技术网

我正在尝试在Delphi函数中使用和释放2个指针。我如何正确地释放它们?

我正在尝试在Delphi函数中使用和释放2个指针。我如何正确地释放它们?,delphi,pointers,delphi-xe3,Delphi,Pointers,Delphi Xe3,我正在使用delphixe3。我试图学习更多关于如何正确使用并释放指针的知识。我有两个指针lpParams和pHolder。我想知道我是否必须使用pHolder的类型指针,以及在这个例程中释放两个pinter的正确方法。多谢各位 function TmyLine.LineOpen(dwLineDevice: Integer; var wMediaMode: Integer;

我正在使用delphixe3。我试图学习更多关于如何正确使用并释放指针的知识。我有两个指针lpParams和pHolder。我想知道我是否必须使用pHolder的类型指针,以及在这个例程中释放两个pinter的正确方法。多谢各位

function TmyLine.LineOpen(dwLineDevice:        Integer;
                             var wMediaMode:  Integer;
                             phLine,
                             plTAPIVersion:       pLongInt): Integer;
  var lOwnership,
      lResult:            LongInt;
      lpParams:     pTLineCallparams;  // first pointer
      pHolder:      Pointer;                        // second pointer
      dwAddressID, dwMediaMode: DWORD;  
begin
  if not bDeviceInitialized then
    lResult := -1
  else
    begin
      pHolder := nil; // default is nil unless we are using the singleaddress method
      lOwnership := 0;
      if FPrivilege.bSingleAddress then
      begin
        lOwnership := lOwnership + LINEOPENOPTION_SINGLEADDRESS;  
        try
          lpParams := AllocMem(SizeOf(TLineCallParams) + 128);   // make up a big enough value
        except
          lpParams := nil;
          exit; // should I exit here? what about if there is an error? do I free pHolder?
        end;
        lpParams.dwTotalSize := sizeof(TLineCallParams) + 128;

        lpParams.dwAddressMode := LINEADDRESSMODE_ADDRESSID;
        pHolder := lpParams;     // is this ok? Do i need a typed pointer?
      end;

      lResult := lineOpen(Fline.hLineApp,       // fnd 64bit, see if longint needs to be dword_ptr
                          dwLineDevice,
                          phLine,
                          plTAPIVersion^,
                          FTAPI.lExtVersion,
                          DWORD_PTR(Self),  //Pointer to the control, it is passed to the Callback routine as the lCallBackInstance parameter
                          lOwnership,
                          wMediaMode,
                          pHolder);    // using the pointer here
      if lResult <> 0  then
        begin
          pHolder := nil;
          lpParams := nil; // is the the right way to do this?

          end
      else
        begin       
          lineSetStatusMessages(temp);
        end;
    end;

  pHolder := nil; //  is this the correct way to free things up?
  if lpParams <> nil then freemem(lpParams, sizeof(TLineCallParams) + 128); 
  LineOpen := lResult;
end;
函数TmyLine.LineOpen(dwLineDevice:Integer;
var wMediaMode:整数;
phLine,
pltAversion:pLongInt):整数;
var lOwnership,
结果:长;
lpParams:pTLineCallparams;//第一个指针
pHolder:指针;//第二个指针
dwAddressID,dwMediaMode:DWORD;
开始
如果未初始化,则
lResult:=-1
其他的
开始
pHolder:=nil;//除非使用singleaddress方法,否则默认值为nil
低能量:=0;
如果FPrivilege.bSingleAddress,则
开始
lOwnership:=lOwnership+LINEOPENOPTION\u SINGLEADDRESS;
尝试
lpParams:=AllocMem(SizeOf(TLineCallParams)+128);//组成一个足够大的值
除了
lpParams:=nil;
退出;//我应该在这里下车吗?如果有错误怎么办?我有空吗?
结束;
lpParams.dwTotalSize:=sizeof(TLineCallParams)+128;
lpParams.dwAddressMode:=LINEADDRESSMODE_ADDRESSID;
pHolder:=lpParams;//这样行吗?我需要键入的指针吗?
结束;
lResult:=lineOpen(Fline.hLineApp,//fnd 64位,查看longint是否需要为dword\u ptr
dwLineDevice,
phLine,
公共交通^,
FTAPI.lExtVersion,
DWORD_PTR(Self),//指向控件的指针,它作为lCallBackInstance参数传递给回调例程
低能,
wMediaMode,
pHolder);//在这里使用指针
如果lResult为0,则
开始
pHolder:=零;
lpParams:=nil;//这样做正确吗?
结束
其他的
开始
lineSetStatusMessages(临时);
结束;
结束;
pHolder:=nil;//这是解放一切的正确方法吗?
如果lpParams为nil,则为freemem(lpParams,sizeof(TLineCallParams)+128);
LineOpen:=lResult;
结束;

首先,您填写的是
dwAddressMode
字段,但不是
dwAddressID
字段。您需要填写
dwAddressID
,否则使用
LINEOPENOPTION\u SINGLEADDRESS
没有意义

其次,
lineOpen()
不拥有传递给它的
LINECALLPARAMS
指针的所有权。退出
lineOpen()
后,无论其结果如何,都必须自行释放内存,例如:

function TmyLine.LineOpen(dwLineDevice: Integer;
                         var wMediaMode: Integer;
                         phLine,
                         plTAPIVersion: pLongInt): Integer;
var
  lOwnership: DWORD;
  lpParams: pTLineCallparams;
begin
  Result := -1;
  if not bDeviceInitialized then Exit;

  lOwnership := 0;

  lpParams := nil;
  try
    if FPrivilege.bSingleAddress then
    begin
      try
        lpParams := AllocMem(SizeOf(TLineCallParams));
      except
        Exit;
      end;

      lpParams.dwTotalSize := sizeof(TLineCallParams);
      lpParams.dwAddressID := ...; // don't forget to fill this in!
      lpParams.dwAddressMode := LINEADDRESSMODE_ADDRESSID;

      lOwnership := LINEOPENOPTION_SINGLEADDRESS;  
    end;

    Result := lineOpen(Fline.hLineApp,
                      dwLineDevice,
                      phLine,
                      plTAPIVersion^,
                      FTAPI.lExtVersion,
                      DWORD_PTR(Self),
                      lOwnership,
                      wMediaMode,
                      lpParams);
  finally
    if lpParams <> nil then
      FreeMem(lpParams, sizeof(TLineCallParams)); 
  end;

  if Result = 0 then
    lineSetStatusMessages(...);
end;

这里有很多问题。很难知道该关注什么。尤其是我们对您调用的API一无所知。@DavidHeffernan对AllocMem的每次调用都应该有对FreeMem的相应调用,否则,它就是一个leak@EProgrammerNotFound是的。“但是问题中的其余代码都充满了问题。”大卫·费弗南在这种情况下,我认为我们应该只局限于回答OP的问题。在我看来,问题很清楚。@David:
lineOpen
是一个来自Win32(Tapi32.dll)的电话API(TAPI)函数。第一个版本可以返回,而无需设置
Result
。FWIW,我认为你应该劝阻询问者以这种方式处理内存不足错误。异常不应被捕获在这里。@Remy,我想添加代码,我是否编辑我的原始帖子?我看不出如何继续一个线程并说,好吧,忽略前面的代码,这个怎么样……。@F.Decker:如果新代码与原始问题相关,您可以编辑原始问题。Remy和@DavidHeffernan,我对第一篇文章进行了编辑并更改了代码。谢谢大家!@大卫·费弗南,我迷路了。当我在这里看我的文章时,上面我为最终审查编辑的代码不在那里。但在它下面我看到了“大卫·赫弗南编辑”。当我点击它时,它会把我带到另一个页面,在那里我请求帮助的代码会显示出来。我必须已经发布了不止一次,因为我没有看到它出现,其中两个帖子是红线,最终版本在那里。版主必须批准它吗?
function TmyLine.LineOpen(dwLineDevice: Integer;
                         var wMediaMode: Integer;
                         phLine,
                         plTAPIVersion: pLongInt): Integer;
var
  lOwnership: DWORD;
  Params: TLineCallparams;
  lpParams: pTLineCallparams;
begin
  Result := -1;
  if not bDeviceInitialized then Exit;

  lOwnership := 0;
  lpParams := nil;

  if FPrivilege.bSingleAddress then
  begin
    Params.dwTotalSize := sizeof(TLineCallParams);
    Params.dwAddressID := ...; // don't forget to fill this in!
    Params.dwAddressMode := LINEADDRESSMODE_ADDRESSID;

    lpParams := @Params;
    lOwnership := LINEOPENOPTION_SINGLEADDRESS;  
  end;

  Result := lineOpen(Fline.hLineApp,
                    dwLineDevice,
                    phLine,
                    plTAPIVersion^,
                    FTAPI.lExtVersion,
                    DWORD_PTR(Self),
                    lOwnership,
                    wMediaMode,
                    lpParams);
  if Result = 0 then
    lineSetStatusMessages(...);
end;