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

周末这两天在家用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.csdn.net/xceman1997/article/details/46405597

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值