【LDA】修正 GibbsLDA++-0.2 中的两个内存问题

本文详述了在使用GibbsLDA++进行文本主题模型实验时遇到的内存访问越界和内存泄露问题,并提供了针对性的解决方案。通过修正随机数生成和内存释放的代码,使得该工具包在Windows平台下运行更加稳定和高效。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

周末这两天在家用LDA做个小实验。在LDA的众多实现的工具包中,GibbsLDA 是应用最广泛的,包括c++版本、java版本等。GibbsLDA++ 是它的C++版本的实现,目前最新版本是0.2版。在实际使用过程中,发现这个实现版本有内存使用问题。我花了一些时间定位到了问题,贴出来供大家参考。


问题1:数组内存访问越界

在model.cpp中,用到了两个矩阵nw和nd,分别存储word-topic关系和document-topic关系。这两个矩阵的大小分别是V * K和 M * K,其中,V是词表大小,M是文档个数,K是topic的个数。在sampling的过程中,用随机数产生器来随机产生topic对应的索引。源程序如下:

int topic = (int)(((double)random() / RAND_MAX) * K);

原则上,topic的索引的取值范围是[0,K-1],不过,上面那行程序,函数random()的取值可以是RAND_MAX,也就是说上述语句产生的topic索引的范围是[0,K],当产生的索引是K的时候,在接下来的运算中,发生数组越界访问。

所以应该把上面的代码修正为:

int topic = (int)(((double)random() / (RAND_MAX+1)) * K);

我实际上是在windows上面用的,windows不支持random()函数,所以改成rand()函数,如下:

int topic = (int)(((double)rand() / (RAND_MAX+1)) * K);

当然,srandom()也要改成srand()。


问题2:内存泄露

内存泄露主要发生在class model的析构函数中,即model::~model()中。产生的原因很简单,作者对于向量的内存释放,用的是delete,而正确的应该用delete []。

例如,原始代码:

if (nw) {
	for (int w = 0; w < V; w++) {
	    if (nw[w]) {
		delete nw[w];
	    }
	}
}

如之前所述,nw是一个矩阵。正确代码是:

if (nw) {
	for (int w = 0; w < V; w++) {
	    if (nw[w]) {
		delete [] nw[w];   //!!!
	    }
	}
}
	delete [] nw;   //!!!

修改了上面两个问题之后,GibbsLDA++-0.2在机器上跑的就很顺畅了。——其实不修正也能跑出结果来:对于内存访问越界,次数并不多,所以影响不大;对于内存泄露,进程退出的时候OS会自动清理改进程所用的内存空间,所以也影响不大。这可能也是这个工具包被这么多人(主要是研究人员)使用,而没人去修正这个问题的原因吧。


完。


转载请注明出处:http://blog.youkuaiyun.com/xceman1997/article/details/46405597

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值