DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: tkzcol
今日帖子: 4
在线用户: 2
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 badwood (badwood) ★☆☆☆☆ -
盒子活跃会员
2018/1/24 12:44:55
标题:
关于结构指针释放的疑惑 浏览:1068
加入我的收藏
楼主: 代码如下:

type
  PJiebaWord = ^CJiebaWord;

  CJiebaWord = record
    word: Pansichar;
    len: cardinal;
  end;

var
  Ahandle: Thandle;
  pw, words: pjiebaword;
  tag: RawByteString;
begin
  Ahandle := NewJieba();
  txt := '测试例句';
  words := Cut(Ahandle, PAnsiChar(txt));
  pw := words;
  while (nil <> pw) and (nil <> pw^.word) do
  begin
    //省略
    inc(pw);
  end;

  FreeWords(words);     //这是API提供的函数
  FreeJieba(Ahandle);

end;
==========
例子中的FreeWords是接口提供的函数,但在XE6及以后,到底有没有必要手动释放words这个结构指针?应该是自动释放的吧?
之所以有此疑惑,是因为上述代码在有的程序中工作正常,放到有的程序中FreeWords会出错。
----------------------------------------------
-
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2018/1/24 17:14:30
1楼: 兰州听谁说会自动释放的?
原生程序,屁股都要自己擦。编译器不会帮你擦这种屁股。

另外就是,之前都给你翻译过一个定义,你自己一定要丢弃,一定要自己搞,那就要自己去核对两边的翻译是否到位。
----------------------------------------------
--
作者:
男 badwood (badwood) ★☆☆☆☆ -
盒子活跃会员
2018/1/24 17:43:07
2楼: 谢谢1楼的帮助。
这是你翻译的代码

  type
  pjiebaword = ^tjiebaword;
  tjiebaword = record
    word: lpcstr;
{$ifdef cpux64}
    len: uint64;
{$else}
    len: uint;
{$endif}
  end;

其中的类型都是DELPHI不支持的,所以我修改了一下。


你提供的包里那个PAS文件是用headcov自动转换的吧,那个不能直接用,我改了一个接口PAS。
这是地址 http://bbs.2ccc.com/attachments/2018/badwood_201812112103.rar

测试使用的代码根据结巴的DEMO和参考你翻译的代码制作的,我建立单独的测试程序可以正常执行。

但将同样代码放在另一个程序(非多线程)里 FreeWords(words); 就会报错。
我看了C++源码,FreeWords就是简单的释放
void FreeWords(CJiebaWord* words) {
  free(words);
}

找不到释放这个指针会报错的原因。


测试代码
==========
type
  PJiebaWord = ^CJiebaWord;

  CJiebaWord = record
    word: Pansichar;
    len: cardinal;
  end;
var
  DICT_PATH, HMM_PATH, USER_DICT, IDF_PATH, STOP_WORDS_PATH: ansistring;
  Ahandle: Thandle;
  txtlen: cardinal;
  txt,newtxt: ansistring;
  pw, words: pjiebaword;
  tag: RawByteString;
begin

  DICT_PATH := './jiebadict/jieba.dict.utf8';
  HMM_PATH := './jiebadict/hmm_model.utf8';
  USER_DICT := './jiebadict/user.dict.utf8';
  IDF_PATH := './jiebadict/idf.utf8';
  STOP_WORDS_PATH := './jiebadict/stop_words.utf8';

  Ahandle := NewJieba(PAnsiChar(DICT_PATH), PAnsiChar(HMM_PATH), PAnsiChar(USER_DICT), PAnsiChar(IDF_PATH),
    PAnsiChar(STOP_WORDS_PATH));
  txt := trim(Msource.Text);
  txt := utf8encode(txt);
  txtlen := length(txt);
  words := Cut(Ahandle, PAnsiChar(txt), txtlen);
  newtxt := '';
  pw := words;
  while (nil <> pw) and (nil <> pw^.word) do
  begin
    tag := UTF8Decode(leftstr(pw^.word, pw^.len));
    newtxt := newtxt + tag + '/';

    inc(pw);
  end;
  Mdest.Lines.Append(newtxt);

  FreeWords(words);
  FreeJieba(Ahandle);
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2018/1/24 17:50:55
3楼: 楼上胡说。
人家的类型 DELPHI 都支持的。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 badwood (badwood) ★☆☆☆☆ -
盒子活跃会员
2018/1/24 18:05:35
3楼: 反复测试后发现是执行了 pw := words; 这一句后, FreeWords(words); 就会报错。

这样能正常释放:
words := Cut(Ahandle, PAnsiChar(txt), txtlen);
FreeWords(words);

下列代码释放就会报错(放在其他程序里时):
words := Cut(Ahandle, PAnsiChar(txt), txtlen);
pw := words; //问题出在这里
FreeWords(words);


所以,C++的下列代码在delphi中应该怎么写才正确呢。


  CJiebaWord* words = Cut(handle, s, len); 
  CJiebaWord* x;
  for (x = words; x && x->word; x++) {
    printf("%*.*s\n", x->len, x->len, x->word);
  }
  FreeWords(words);
  FreeJieba(handle);
----------------------------------------------
-
作者:
男 badwood (badwood) ★☆☆☆☆ -
盒子活跃会员
2018/1/24 18:10:00
4楼: @ wang_80919 是我无知了,因为搜索帮助没找到lpcstr就以为不支持。
此帖子包含附件:
JPEG 图像
大小:83.4K
----------------------------------------------
-
作者:
男 badwood (badwood) ★☆☆☆☆ -
盒子活跃会员
2018/1/24 18:19:26
5楼: 按照bahamut8348 的代码修改了接口定制,但3楼描述的问题仍然存在

Project test.exe raised exception class $C0000005 with message 'access violation at 0x25fde01c: read of address 0x25fde01c'.
----------------------------------------------
-
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2018/1/24 19:29:36
6楼: 所以说吧,兰州基本不看人家的说明的。
之前帮你打包的时候就已经说了,没有修改约定,全部都是cdecl。
兰州看看自己的定义是怎么写的。。。
此帖子包含附件:
PNG 图像
大小:46.6K
----------------------------------------------
--
作者:
男 badwood (badwood) ★☆☆☆☆ -
盒子活跃会员
2018/1/24 20:29:04
7楼: 不是不看,是有看没有懂啊,这个是在headcov翻译的接口基础上改来的。
去掉了 stdcall ,现在OK了,感谢bahamut8348。
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行129.8828毫秒 RSS